ASP.NET Core使用自定义身份验证处理程序与Cookie身份验证

7

我正在尝试创建自己的AuthenticationHandler并与cookie验证一起使用:

services.AddAuthentication(options =>
  {
  options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
  options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
  options.DefaultChallengeScheme = MyAuth.Scheme;
  })
  .AddCookie()
  .AddScheme<MyAuthenticationOptions, MyAuthenticationHandler>(MyAuth.Scheme, "My auth scheme", options => { });

.

public MyAuthenticationHandler(...) : base(...) {}

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        throw new NotImplementedException();  
    }    

    protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
    {                     
        var myUser = await DoAuth();

        if (!myUser.IsAuthenticated)
        {
            if (Context.Request.Query.ContainsKey("isRedirectedFromSSO"))
            {
                Context.Response.Redirect("/unauthorized");
                return;
            }
            else
            {
                Context.Response.Redirect("url to sso");
                return;
            }              
        }    

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Username),            
        };

        var identity = new ClaimsIdentity(claims, MyAuth.Scheme);
        var claimsPrincipal = new ClaimsPrincipal(identity);

        var authProperties = new AuthenticationProperties {};

        await Context.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            claimsPrincipal,
            authProperties);

        Context.Response.Redirect(Request.GetEncodedUrl());
    }
}
  1. 如果存在有效的认证cookie,则使用该cookie进行认证
  2. 如果不存在有效的认证cookie,则使用我的认证方式发起挑战,并在成功后创建一个认证cookie

这种实现方法在实践中是可行的,但我觉得在HandleChallenge方法中进行实际认证并在失败时重定向有点奇怪。 另外,我也觉得从一个AuthenticationHandler(cookie)调用另一个(MyAuthenticationHandler)有点奇怪。

如何正确设置以便我可以在HandleAuthenticate方法中执行实现? 在我的当前实现中,该方法实际上从未被调用。

此外,从另一个身份验证处理程序调用一个身份验证处理程序是否可以?

P.S. 我查看了几篇其他文章(包括这个这个这个),但我没有找到解答我的问题。任何帮助都将不胜感激。


如何链接多个中间件? - Mohammed Noureldin
怎么做呢?你能提供一个基本的例子链接吗? :) - severin
你的SSO身份提供者是谁? - Win
我想我一开始误解了问题。现在我认为我知道问题所在了。为什么你要在HandleChallenge中进行这个过程,而不是在HandleAuthentication中呢? - Mohammed Noureldin
这正是我的问题 :) - severin
显示剩余4条评论
1个回答

6
我认为你需要用ASP.NET Core 2.1的一些新功能来解决问题。
以下是如何根据httpcontext数据“选择”身份验证方案的示例: <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.1.0-rc1-final" />
builder.AddPolicyScheme("scheme", "scheme", opts =>
{
    opts.ForwardDefaultSelector = ctx =>
    {
        if (ctx.Request.Query.ContainsKey("isRedirectedFromSSO"))
        {               
            return null; // or ctx.ForbidAsync(), not sure here.
        }

        return OpenIdConnectDefaults.AuthenticationScheme; // or your own sso scheme, whatever it may be here.
    };
})
.AddCookie()
.AddOpenIdConnect();

请查看这个 GitHub 帖子,其中涉及 IT 技术相关内容。

1
也可以查看这个链接,非常有用。https://github.com/aspnet/AspNetCore/issues/4648#issuecomment-410330370 - Suketu Bhuta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接