ASP.Net Core中的自定义身份验证机制

时间:2016-11-27 17:21:47

标签: security authentication asp.net-core handler

我需要使用登录页面中的外部API对我的用户进行身份验证。如果外部API的身份验证成功,那么我会在会话中存储一个AuthToken。

要检查请求是否有效,我已创建以下授权处理程序

public class ExtApiStoreRequirement : IAuthorizationRequirement
{
}
public class ExtApiAuthorizationHandler : AuthorizationHandler<ExtApiStoreRequirement>
{

    IHttpContextAccessor _accessor;
    public ExtApiAuthorizationHandler(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ExtApiStoreRequirement requirement)
    {
        var authState = GET_AUTH_FROM_SESSION(_accessor.HttpContext.Session);


        if (authState!=null)
        {
            _accessor.HttpContext.Response.Redirect("/Account/Login");
            //context.Fail(); <-- I removed that because it was responding an empty page
            context.Succeed(requirement);
        }
        else
            context.Succeed(requirement);

        return Task.CompletedTask;
    }
}

我在startup.cs上注册了这个处理程序

  services.AddAuthorization(options =>
        {
            options.AddPolicy("ExtApi",
                              policy => policy.Requirements.Add(new ExtApiStoreRequirement()));
        });

这种方法有效但我不自信,因为我必须调用context.Succeed(requirement);才能使重定向工作。如果我调用context.Fail(),则不会发生重定向,我看到的只是一个空页。

此方法是否存在任何安全问题,或者我可以安全地使用它?

1 个答案:

答案 0 :(得分:0)

您的实施是针对授权而非身份验证。我认为编写自定义身份验证中间件不是创建授权策略,而是适合您的情况。

首先了解如何实施自定义身份验证Simple token based authentication/authorization in asp.net core for Mongodb datastore

为您的案例HandleAuthenticateAsync实施上述方式应如下所示:

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    AuthenticateResult result = null;
    var principal = GetPrincipalFromSession();
    if(principal != null)
    {
         result = AuthenticateResult.Success(new AuthenticationTicket(principal,
                    new AuthenticationProperties(), Options.AuthenticationScheme));
    }
    else
    {
         result = AuthenticateResult.Skip();
    }
    return result;
}

根据评论进行更新

protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext context)
{    
     Response.Redirect(Options.LoginPath);// you need to define LoginPath        
     return true;
}

此外,您应该在用户登录时将主体存储在会话中。