From a5338be49f291ade84a849c717df4dbc13be6465 Mon Sep 17 00:00:00 2001 From: Demis Bellot Date: Mon, 29 Apr 2024 16:31:20 +0800 Subject: [PATCH] Call PopulateFromClaims() from IdentityJwtAuthProvider populated bearer tokens --- .../Auth/IdentityJwtAuthProvider.cs | 24 ++++------ .../IdentityJwtAuthProviderTests.cs | 46 +++++++++++++++++++ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/ServiceStack/src/ServiceStack.Extensions/Auth/IdentityJwtAuthProvider.cs b/ServiceStack/src/ServiceStack.Extensions/Auth/IdentityJwtAuthProvider.cs index 06f6127afbf..c35c792b7af 100644 --- a/ServiceStack/src/ServiceStack.Extensions/Auth/IdentityJwtAuthProvider.cs +++ b/ServiceStack/src/ServiceStack.Extensions/Auth/IdentityJwtAuthProvider.cs @@ -310,10 +310,7 @@ public override bool IsAuthorized(IAuthSession session, IAuthTokens tokens, Auth var principal = new JwtSecurityTokenHandler().ValidateToken(bearerToken, Options!.TokenValidationParameters, out SecurityToken validatedToken); - var jwtToken = (JwtSecurityToken)validatedToken; - var claims = jwtToken.Claims.ToList(); - - var jwtSession = CreateSessionFromClaims(req, claims); + var jwtSession = CreateSessionFromClaims(req, principal); var to = jwtSession.ConvertTo(); to.UserId = jwtSession.UserAuthId; return (to as object).InTask(); @@ -331,21 +328,13 @@ public Task PreAuthenticateAsync(IRequest req, IResponse res) if (!string.IsNullOrEmpty(token) && !(req.Items.TryGetValue(Keywords.Session, out var oSession) && oSession is IAuthSession { IsAuthenticated: true })) { - List claims; var user = req.GetClaimsPrincipal(); - if (user.IsAuthenticated()) - { - claims = user.Claims.ToList(); - } - else + if (!user.IsAuthenticated()) { - var principal = new JwtSecurityTokenHandler().ValidateToken(token, + user = new JwtSecurityTokenHandler().ValidateToken(token, Options!.TokenValidationParameters, out SecurityToken validatedToken); - - var jwtToken = (JwtSecurityToken)validatedToken; - claims = jwtToken.Claims.ToList(); } - var session = CreateSessionFromClaims(req, claims); + var session = CreateSessionFromClaims(req, user); req.Items[Keywords.Session] = session; } return Task.CompletedTask; @@ -410,8 +399,9 @@ public async Task MessageReceivedAsync(MessageReceivedContext ctx) } } - public virtual IAuthSession CreateSessionFromClaims(IRequest req, List claims) + public virtual IAuthSession CreateSessionFromClaims(IRequest req, ClaimsPrincipal principal) { + var claims = principal.Claims.ToList(); var sessionId = claims.FirstOrDefault(x => x.Type == "jid")?.Value ?? HostContext.AppHost.CreateSessionId(); var session = SessionFeature.CreateNewSession(req, sessionId); @@ -423,6 +413,8 @@ public virtual IAuthSession CreateSessionFromClaims(IRequest req, List cl claims.Each(x => claimMap.Add(new(x.Type, x.Value))); session.PopulateFromMap(claimMap); + (session as IAuthSessionExtended)?.PopulateFromClaims(req, principal); + OnSessionCreated?.Invoke(session, claims, req); HostContext.AppHost.OnSessionFilter(req, session, sessionId); diff --git a/ServiceStack/tests/ServiceStack.Extensions.Tests/IdentityJwtAuthProviderTests.cs b/ServiceStack/tests/ServiceStack.Extensions.Tests/IdentityJwtAuthProviderTests.cs index 999fd3c4599..f5f65da1ba9 100644 --- a/ServiceStack/tests/ServiceStack.Extensions.Tests/IdentityJwtAuthProviderTests.cs +++ b/ServiceStack/tests/ServiceStack.Extensions.Tests/IdentityJwtAuthProviderTests.cs @@ -20,6 +20,7 @@ using NUnit.Framework; using ServiceStack.Auth; using ServiceStack.Data; +using ServiceStack.Messaging; using ServiceStack.OrmLite; using ServiceStack.Text; using ServiceStack.Web; @@ -58,6 +59,22 @@ public class Roles public const string Employee = nameof(Employee); } +[ValidateIsAuthenticated] +public class MqBearerToken : IHasBearerToken, IReturn +{ + public int Id { get; set; } + public string? BearerToken { get; set; } +} + +public class BackgroundAuthServices : Service +{ + public object Any(MqBearerToken request) + { + request.Id++; + return request; + } +} + public class IdentityJwtAuthProviderTests { private static readonly int TotalRockstars = AutoQueryAppHost.SeedRockstars.Length; @@ -166,6 +183,10 @@ public override void Configure() log.LogInformation("Seeding Database..."); using var db = GetDbConnection(); AutoQueryAppHost.SeedDatabase(db); + + var mqService = Resolve(); + mqService.RegisterHandler(ExecuteMessage); + mqService.Start(); } } @@ -245,6 +266,8 @@ public IdentityJwtAuthProviderTests() }); }); + services.AddSingleton(c => new BackgroundMqService()); + var app = builder.Build(); app.UseAuthorization(); @@ -275,6 +298,18 @@ private async Task CreateExpiredTokenAsync() return jwt; } + private async Task GetBearerTokenAsync() + { + var authClient = GetClient(); + var response = await authClient.SendAsync(new Authenticate + { + provider = "credentials", + UserName = Username, + Password = Password, + }); + return authClient.GetTokenCookie(); + } + private async Task GetRefreshTokenAsync() { var authClient = GetClient(); @@ -425,6 +460,17 @@ public async Task Endpoints_Can_Auto_reconnect_with_RefreshToken_after_expired_t response = await client.SendAsync(request); Assert.That(response.Result, Is.EqualTo("Hello, test")); } + + [Test] + public async Task Can_authenticate_with_BearerToken_in_MQ() + { + var bearerToken = await GetBearerTokenAsync(); + + await ServiceStackHost.Instance.ExecuteMessageAsync(new Message(new MqBearerToken + { + BearerToken = bearerToken, + })); + } } #endif \ No newline at end of file