簡體   English   中英

如何自定義 ASP .NET Web API JWT 令牌響應?

[英]How to customize ASP .NET Web API JWT token response?

我正在使用帶有 Web API 的 Asp.net Webform 項目。 我配置了基於 JWT 令牌的身份驗證,現在我想自定義身份驗證響應

這是我的配置,

  1. 啟動文件

    public class Startup { public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); // Web API routes config.MapHttpAttributeRoutes(); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); ConfigureOAuth(app); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); WebApiConfig.Register(config); } public void ConfigureOAuth(IAppBuilder app) { String apiHttpOnly = ConfigurationManager.AppSettings["AllowInsecureHttp"]; String tokenTimeSpan = ConfigurationManager.AppSettings["tokenTimeSpanFromMinutes"]; bool allowInsecureHttp = !String.IsNullOrEmpty(apiHttpOnly) ? Convert.ToBoolean(apiHttpOnly) : false; int accessTokenExpireTimeSpan = !String.IsNullOrEmpty(tokenTimeSpan) ? Convert.ToInt32(tokenTimeSpan) : 60; var authProvider = new AuthorizationServiceProvider(); OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions { //For Dev enviroment only (on production should be AllowInsecureHttp = false) AllowInsecureHttp = allowInsecureHttp, TokenEndpointPath = new PathString("/api/authenticate"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(accessTokenExpireTimeSpan), Provider = authProvider }; app.UseOAuthAuthorizationServer(options); } }
  2. 授權服務提供者

     public class AuthorizationServiceProvider : OAuthAuthorizationServerProvider { public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { context.Validated(); return base.ValidateClientAuthentication(context); } public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var identity = new ClaimsIdentity(context.Options.AuthenticationType); if (Membership.ValidateUser(context.UserName, context.Password)) { identity.AddClaim(new Claim(ClaimTypes.Role, "admin")); identity.AddClaim(new Claim("username", context.UserName)); identity.AddClaim(new Claim(ClaimTypes.Name, "admin admin")); context.Validated(identity); } else { context.SetError("invalid_grant", "Provide username and password is incorrect."); } return base.GrantResourceOwnerCredentials(context); } }

當我使用正確的憑據調用 API 時,它返回如下

{
    "access_token": "uEwmXl6N0mJXVUZesxA_2tG5lIuZUIUDaxtjAl0QGE6j2-J7n4c63zboOUClGjRQf1IDY9-nBgyq0HP5WR7MMxTYoHGIyiHIbcKu9AYwhECCGaVBCxY2Ounhit4N1pYK1vV6uX6AcoA-a0xhytF8Jz27D77ZvCLi3PuUQDEXSp0pkGG796wu1fRZCaRsCB-kLoa-_V7KJaGGhhoybN_c0GNOBhhwmGpx6Js26-Vx-lmWpfsPUE1aKrJfx-oMcyE5x7CooAlx4vA6iZhnNfmYdRejRKoKKnObyuAsym7mVdZY3bpv",
    "token_type": "bearer",
    "expires_in": 5183999
}

我想通過添加一些額外的屬性來自定義響應,例如,

{
    "access_token": "uEwmXl6N0mJXVUZesxA_2tG5lIuZUIUDaxtjAl0QGE6j2-J7n4c63zboOUClGjRQf1IDY9-nBgyq0HP5WR7MMxTYoHGIyiHIbcKu9AYwhECCGaVBCxY2Ounhit4N1pYK1vV6uX6AcoA-a0xhytF8Jz27D77ZvCLi3PuUQDEXSp0pkGG796wu1fRZCaRsCB-kLoa-_V7KJaGGhhoybN_c0GNOBhhwmGpx6Js26-Vx-lmWpfsPUE1aKrJfx-oMcyE5x7CooAlx4vA6iZhnNfmYdRejRKoKKnObyuAsym7mVdZY3bpv",
    "token_type": "bearer",
    "expires_in": 5183999,
    "attribute1" : "abc",
    "attribute2" : "ert"
}

任何人都有這樣做的想法?

最后,我調查問題並找出解決方案。 我把它貼在這里,也許它可以幫助某人。

  1. 添加身份驗證屬性

    var props = new AuthenticationProperties(new Dictionary<string, string> { { "attribute1" , "abc" }, { "attribute2" , "ert" } });
  2. 然后使用AuthenticationTicket創建票證

    var ticket = new AuthenticationTicket(identity, props);
  3. 將票添加到上下文

    context.Validated(ticket);
  4. 然后實現覆蓋方法TokenEndpoint

     public override Task TokenEndpoint(OAuthTokenEndpointContext context) { foreach (KeyValuePair<string, string> property in context.Properties.Dictionary) { context.AdditionalResponseParameters.Add(property.Key, property.Value); } return Task.FromResult<object>(null); }

最后AuthorizationServiceProvider類就像,

public class AuthorizationServiceProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return base.ValidateClientAuthentication(context);
    }

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var identity = new ClaimsIdentity(context.Options.AuthenticationType);

        if (string.IsNullOrEmpty(context.UserName) || string.IsNullOrEmpty(context.Password))
        {
            context.SetError("invalid_request", "No username or password are provided.");
        }
        else if (Membership.ValidateUser(context.UserName, context.Password))
        {
            
            identity.AddClaim(new Claim("username", context.UserName));
            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));

            /*
             * All custom response props are define here.
             * --------usage----------
             * use as dictionary
             * */
            var props = new AuthenticationProperties(new Dictionary<string, string>
            {
                //{
                //    "test" , "val"
                //}
            });

            var ticket = new AuthenticationTicket(identity, props);


            context.Validated(ticket);
        }
        else
        {
            context.SetError("invalid_grant", "Provide username and password is incorrect.");

        }

        return base.GrantResourceOwnerCredentials(context);
    }

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key, property.Value);
        }
        return Task.FromResult<object>(null);
    }
}

欲了解更多信息 - https://stackoverflow.com/a/26369622/8403632

示例示例 - https://github.com/Leftyx/OwinWebApiBearerToken

暫無
暫無

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

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