。NET Core Web API中使用自定义属性的JWT身份验证

问题描述 投票:1回答:1

我目前正在将我的Web API 2.0转换为.NET Core Web API,但是我正在努力解决其中一部分。

在我现有的API中,我有一个带有以下代码的属性:

public class JwtAuthentication : Attribute, IAuthenticationFilter
{
    public string Realm { get; set; }

    public bool AllowMultiple => false;

    public async Task AuthenticateAsync(
        HttpAuthenticationContext context, 
        CancellationToken cancellationToken)
    {
        var request = context.Request;

        var authorization = request.Headers.Authorization;

        // checking request header value having required scheme "Bearer" or not.
        if (authorization == null ||
            authorization.Scheme.ToLowerInvariant() != "bearer" ||
            string.IsNullOrEmpty(authorization.Parameter))
        {
            context.ErrorResult = new AuthenticationFailureResult("JWT Token is Missing", request);
            return;
        }

        // Getting Token value from header values.
        var token = authorization.Parameter;
        var principal = await AuthJwtToken(token);

        if (principal == null)
        {
            context.ErrorResult = new AuthenticationFailureResult("Invalid JWT Token", request);
        }
        else
        {
            context.Principal = principal;
        }
    }

    private static bool ValidateToken(string token, out ICollection<Claim> claims)
    {
        claims = null;

        var simplePrinciple = JwtAuthManager.GetPrincipal(token);

        if (simplePrinciple == null)
        {
            return false;
        }

        var identity = simplePrinciple.Identity as ClaimsIdentity;

        if (identity == null)
        {
            return false;
        }

        if (!identity.IsAuthenticated)
        {
            return false;
        }

        var usernameClaim = identity.FindFirst(ClaimTypes.Name);
        var emailClaim = identity.FindFirst(ClaimTypes.Email);

        var username = usernameClaim?.Value;
        var email = emailClaim?.Value;

        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(email))
        {
            return false;
        }

        claims = identity.Claims.ToList();

        return true;
    }

    protected Task<IPrincipal> AuthJwtToken(string token)
    {
        if (ValidateToken(token, out var claims))
        {
            var identity = new ClaimsIdentity(claims, "Jwt");

            IPrincipal user = new ClaimsPrincipal(identity);

            return Task.FromResult(user);
        }

        return Task.FromResult<IPrincipal>(null);
    }

    public Task ChallengeAsync(
        HttpAuthenticationChallengeContext context, 
        CancellationToken cancellationToken)
    {
        Challenge(context);
        return Task.FromResult(0);
    }

    private void Challenge(HttpAuthenticationChallengeContext context)
    {
        string parameter = null;

        if (!string.IsNullOrEmpty(Realm))
        {
            parameter = "realm=\"" + Realm + "\"";
        }

        context.ChallengeWith("Bearer", parameter);
    }
}

如果我正确理解,在ASP.NET Core中,我要做的就是在启动时定义以下内容:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>  
    {  
        options.TokenValidationParameters = new TokenValidationParameters  
        {  
            ValidateIssuer = true,  
            ValidateAudience = true,  
            ValidateLifetime = true,  
            ValidateIssuerSigningKey = true,  
            ValidIssuer = Configuration["Jwt:Issuer"],  
            ValidAudience = Configuration["Jwt:Issuer"],  
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))  
        };  
    });

而且我不确定是否需要以下内容,但看起来像这样:

services.AddMvc(); 

而且我所能做的就是使用[Authorize]属性,但是如果我想复制在ASP.NET MVC Web API 2.0中使用的属性怎么办?

我应该吗?我喜欢这样的事实,我可以看到令牌出现问题的地方。如果可以相同的方式使用它并假设可以这样做,我该怎么做?谷歌搜索解决方案时,我还没有找到任何有用的方法?

谢谢。

c# asp.net-web-api asp.net-core-webapi
1个回答
0
投票

我想您不想重新发明整个承载令牌认证轮。

如果要自定义事件的处理方式,可以使用JwtBearerOptions.Events Property将您自己的委托挂接到一个或多个事件上。 ([OnAuthenticationFailed PropertyOnChallenge PropertyOnMessageReceived PropertyOnTokenValidated Property)。

示例失败的身份验证日志记录。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>  
    {  
        options.TokenValidationParameters = new TokenValidationParameters  
        {  
            ValidateIssuer = true,  
            ValidateAudience = true,  
            ValidateLifetime = true,  
            ValidateIssuerSigningKey = true,  
            ValidIssuer = Configuration["Jwt:Issuer"],  
            ValidAudience = Configuration["Jwt:Issuer"],  
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))  
        };

    options.Events.OnAuthenticationFailed = (context) =>
    {
        // Log failed authentication here

        // Return control back to JWT Bearer middleware
        return Task.CompletedTask;
    }
});

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.