簡體   English   中英

如何使用ServiceStack將數據庫檢索值自定義聲明添加到JWT令牌

[英]How to add a database retrieved value custom claim to JWT Token using ServiceStack

在AppHost.Configure中我有以下代碼:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new IAuthProvider[] {
        new JwtAuthProvider
        {
            HashAlgorithm = "HS256",
            RequireSecureConnection = requireSecureConnection,
            AuthKeyBase64 = _configuration["AuthSettings:JwtAuthKeyBase64"],//Settings.Value.JwtAuthKeyBase64,
            ExpireTokensIn        = TimeSpan.FromHours(_configuration["AuthSettings:ExpireTokensIn"].ToDouble()),  // JWT Token Expiry
            ExpireRefreshTokensIn = TimeSpan.FromHours(_configuration["AuthSettings:ExpireRefreshTokensIn"].ToDouble()), // Refresh Token Expiry,
            CreatePayloadFilter = (payload,session) => {
                    payload["ZipCode"] = "value_from_database_for_user";
            }
        },
        new CustomCredentialsAuthProvider(), //HTML Form post of User/Pass
    }));

上面的代碼是標准的ServiceStack JwtAuthProvider代碼。

您可以在上面的代碼中看到綁定到CreatePayloadFilter的匿名函數的實現想要從數據庫中檢索值,用戶的ZipCode是值並將其作為自定義聲明添加到令牌。

出於許多顯而易見的原因,在AppHost中實現用戶ZipCode的檢索並不容易,優雅或系統/體系結構合理。 此外它甚至不可能,因為我沒有UserId,AppHost只是在服務啟動時運行的啟動配置代碼。

您還可以在上面的代碼中看到我已經實現了CustomCredentialsAuthProvider ,我可以在CustomCredentialsAuthProvider為登錄用戶加載會話數據,ServiceStack將映射會話值以補充相應的JWT聲明,但我無法通過ServiceStack添加自定義聲明session對象,這里是CustomCredentialsAuthProvider的實現:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService,
        string userName, string password)
    {
        return true;
        //throw new NotImplementedException();
    }

    public override IHttpResult OnAuthenticated(IServiceBase authService,
        IAuthSession session, IAuthTokens tokens,
        Dictionary<string, string> authInfo)
    {
        //Fill IAuthSession with data you want to retrieve in the app eg:
        session.FirstName = "some_firstname_from_db";
        session.LastName = "some_lastname_from_db";
        session.Roles = new List<string> {"role1", "role2"};
        session.Permissions = new List<string> { "permission1", "permission2" };
        session.Email = "test@test.com";
        session.AuthProvider = "credentials";

        //...

        //Call base method to Save Session and fire Auth/Session callbacks:
        return base.OnAuthenticated(authService, session, tokens, authInfo);

        //Alternatively avoid built-in behavior and explicitly save session with
        //authService.SaveSession(session, SessionExpiry);
        //return null;
    }
}

如何向ServiceStack框架創建JWT添加自定義聲明,該聲明的值來自數據庫,此代碼的實現不是AppHost.cs中的函數綁定,我甚至沒有UserId來檢索值?

聽起來您想要使用Custom UserSession來保存其他元數據,您可以在注冊AuthFeature時告訴ServiceStack使用您的自定義會話,例如:

Plugins.Add(new AuthFeature(() => new CustomUserSession(), ...)

之后,您可以將UserSession CustomUserSession轉換為CustomUserSession以訪問其他屬性。

要向JWT令牌添加其他元數據,您可以使用CreatePayloadFilter將數據添加到JWT令牌和相應的PopulateSessionFilter ,以使用其他數據填充Custom UserSession。

盡管@mythz提供了答案,我想提供我的最終代碼:

CustomerUserSession

[DataContract]
public class CustomUserSession: AuthUserSession
{
    [DataMember]
    public string ZipCode { get; set; }
}

CustomCredentialsAuthProvider因為我有一個包含所有帳戶信息的舊數據庫:

public override bool TryAuthenticate(IServiceBase authService,
        string userName, string password)
    {
        return true;
    }

    public override IHttpResult OnAuthenticated(IServiceBase authService,
        IAuthSession session, IAuthTokens tokens,
        Dictionary<string, string> authInfo)
    {
        var customUserSession = (CustomUserSession) session;
        //Fill IAuthSession with data you want to retrieve in the app eg:
        customUserSession.FirstName = "some_firstname_from_db";
        customUserSession.LastName = "some_lastname_from_db";
        customUserSession.Roles = new List<string> {"role1", "role2"};
        customUserSession.Permissions = new List<string> { "permission1", "permission2" };
        customUserSession.Email = "test@test.com";
        customUserSession.AuthProvider = "credentials";
        customUserSession.CreatedAt = DateTime.UtcNow;
        customUserSession.ZipCode = "92123";


        //Call base method to Save Session and fire Auth/Session callbacks:
        return base.OnAuthenticated(authService, session, tokens, authInfo);
    }

我的AppHost添加了ServiceStack AuthFeature

Plugins.Add(new AuthFeature(() => new CustomUserSession(),
    new IAuthProvider[] {
        new JwtAuthProvider
        {
            HashAlgorithm = "HS256",
            RequireSecureConnection = requireSecureConnection,
            AuthKeyBase64 = _configuration["AuthSettings:JwtAuthKeyBase64"],//Settings.Value.JwtAuthKeyBase64,
            ExpireTokensIn        = TimeSpan.FromHours(_configuration["AuthSettings:ExpireTokensIn"].ToDouble()),  // JWT Token Expiry
            ExpireRefreshTokensIn = TimeSpan.FromHours(_configuration["AuthSettings:ExpireRefreshTokensIn"].ToDouble()), // Refresh Token Expiry,
            CreatePayloadFilter = (payload,session) => {
                    payload["zipCode"] = ((CustomUserSession)session).ZipCode;
            },
            PopulateSessionFilter = (session, token, req) => {
                ((CustomUserSession) session).ZipCode = token["zipCode"];
            }
        },
        new CustomCredentialsAuthProvider() //HTML Form post of User/Pass
    }));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM