[ASP.NET MVC][OWIN]Web API使用JWT(Json Web Token)進行驗證授權

  • 4654
  • 0

在ASP.NET Web API 2中如何使用JWT進行驗證授權的相關設定

 

1.安裝Nuget套件OWIN Host SystemWeb

Install-Package Microsoft.Owin.Host.SystemWeb

提供OWIN應用運行的Host 整合ASP.NET Pipeline

2.安裝Nuget套件OWIN Security Jwt

Install-Package Microsoft.Owin.Security.Jwt

提供JWT驗證授權的OWIN Middleware

3.加入Startup啟用類別(OWIN運行的進入點)

OWIN Startup Class

4.啟用JWT Bearer Authentication

// Startup.cs
public void Configuration(IAppBuilder app)
{
    var audience = ConfigurationManager.AppSettings["Audience"];
    var issuer = ConfigurationManager.AppSettings["Issuer"];
    var secret = ConfigurationManager.AppSettings["SignKey"];

    app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
    {
        //Provider = new MyOAuthBearerAuthenticationProvider(),
        AuthenticationMode = AuthenticationMode.Active,
        AllowedAudiences = new[] { audience },
        IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
        {
            new SymmetricKeyIssuerSecurityTokenProvider(issuer, System.Text.Encoding.UTF8.GetBytes(secret))
        },
        TokenValidationParameters = new TokenValidationParameters()
        {
            //ValidateAudience = false,
            ValidAudience = audience,
            //AudienceValidator = CustomAudienceValidator,

            //ValidateIssuer = false,
            ValidIssuer = issuer,
            //IssuerValidator = CustomIssuerValidator,

            IssuerSigningKey = new InMemorySymmetricSecurityKey(
                Encoding.UTF8.GetBytes(secret))
        }
    });
}
InMemorySymmetricSecurityKey需要加入"System.IdentityModel"參考

5.產生Token的API

網路上大多使用UseOAuthAuthorizationServer產生Token,

這邊改用自訂的API產生並回傳Token

[Route("Login")]
//[AllowAnonymous]
[HttpPost]
public object Login(TokenRequest request)
{
    string signKey = ConfigurationManager.AppSettings["SignKey"];
    string issuer = ConfigurationManager.AppSettings["Issuer"];
    string audience = ConfigurationManager.AppSettings["Audience"];
    if (request.Username == "Jon" && request.Password == "123")
    {
        var claims = new[]
        {
            //自訂Payload附帶其他Identity其他屬性的type & value map宣告
            new Claim(ClaimTypes.Name, request.Username),
            new Claim(ClaimTypes.Role, "AdminRole")
        };
        var key = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);

        var token = new JwtSecurityToken(
            issuer: issuer,
            audience: audience,
            claims: claims,
            expires: DateTime.Now.AddMinutes(30),
            signingCredentials: creds);

        return new
        {
            token = new JwtSecurityTokenHandler().WriteToken(token)
        };
        ;
    }
    return BadRequest("Could not verify username and password");
}

6.測試

>取得Token

>使用Token取得資料

搭配[Authorize]檢查驗證

進階使用:

  • 允許來自Query String的Token:
    public class MyOAuthBearerAuthenticationProvider : IOAuthBearerAuthenticationProvider
    {
        public Task RequestToken(OAuthRequestTokenContext context)
        {
            if (context.Request.Method.Equals("GET") && context.Request.Query["token"] !=null)
                context.Token = context.Request.Query["token"];
            return Task.CompletedTask;
        }
    
        public Task ValidateIdentity(OAuthValidateIdentityContext context)
        {
            return Task.CompletedTask;
        }
    
        public Task ApplyChallenge(OAuthChallengeContext context)
        {
            return Task.CompletedTask;
        }
    }
    

     

延伸閱讀: