且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用Cookie身份验证的ASP.NET Core 2.0自定义中间件

更新时间:2023-02-16 10:46:08

简短答案:您应该使用自定义的AuthorizationHandler来验证&检索索赔.

Short answer: you should use a custom AuthorizationHandler to authenticate & retrieve claims.

长答案:使用ASP.NET CORE,您应该远离身份验证中间件.相反,您应该使用AuthenticationHandler microsoft

Long answer: With ASP.NET CORE you should walk away from authentication middleware. Instead you should use an AuthenticationHandler microsoft

要创建自定义的身份验证处理程序,您将需要创建一个继承自AuthenticationHandler<TOption>的新类. TOption是一个简单的类,用于将参数传递给处理程序.

To create a custom Authentication handler, you will need to create a new class inheriting from AuthenticationHandler<TOption>. TOption is a simple class used to pass parameters to your handler.

public class TecMobileOptions : AuthenticationSchemeOptions
{ 
   // Add your options here
}

public class MyNewHandler : AuthenticationHandler<MyOptions>
{
    private readonly ILogger _logger;

    public TecMobileHandler(
        IOptionsMonitor<MyOptions> options,
        ILoggerFactory loggerFactory,
        UrlEncoder encoder,
        ISystemClock clock) : base(options, loggerFactory, encoder, clock)
    {
       // Inject here your DbContext
        _logger = loggerFactory.CreateLogger("name...");
    }
}

然后,您将需要实现HandleAuthenticateAsync方法.必要时,Auth中间件将调用它:

Then you will need to implement the HandleAuthenticateAsync method. It will be called by the Auth middleware when necessary:

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var authorization = Request.Headers["UserId"].ToString();
        (...)
        return AuthenticateResult.Success(
            new AuthenticationTicket(**your claims**, Scheme.Name));
    }

此方法返回的声明将通过HttpContext.User对象提供.

Claims returned by this method will be available through the HttpContext.User object.

完成后,您将需要将方案添加到身份验证构建器中.

Once that done, you will need to add your scheme to the authentication builder.

services.AddAuthentication()
   .AddCookie("MyAuthenticationCookie");
   .AddScheme<MyOptions, MyHandler>("MyHandlerName");

不要忘记在Startup.cs/配置方法中添加以下代码行

Don't forget to add in Startup.cs / Configure methods the following code line

 app.UseAuthentication();

最后,您需要在要保护的所有类/方法上添加Authorize属性

Finally, you will need to add the Authorize attribute on all classes/methods you want to secure

[Authorize(AuthenticationSchemes = "MyHandlerName")]
public class MyControllerController : BaseController
{  }

OR

[Authorize(AuthenticationSchemes = "MyHandlerName")]
public IActionResult MyMethod()
{  }

这里的解决方案涵盖了完整的登录过程. 考虑一下您定义了两种身份验证方案 -基于Cookie的称为CookieScheme -AutoSignInScheme:按照上述步骤创建相应的处理程序

Here the solution covering the full login process. Let's consider you define two authentication schemes - Cookie based is called CookieScheme - AutoSignInScheme: create the corresponding handler following the steps above

[Authorize(AuthenticationSchemes = "CookieScheme")]
public class SecuredController : Controller
{
     (...)
}

然后您需要添加AccountController

public class AccountController : Controller
{
    [HttpGet]
    [Authorize(AuthenticationSchemes = "AutoSignInScheme")]
    public async Task<IActionResult> AutoSignIn(string returnUrl)
    {
        await HttpContext.SignInAsync(
           "CookieScheme",
           new ClaimsPrincipal(new ClaimsIdentity(User.Claims, "CookieScheme")));
        return Redirect(returnUrl);
    }
 }

在您的Startup.cs中,添加以下行:

In your Startup.cs, add the following lines:

       services.AddAuthentication()
            .AddCookie("CookieScheme", opts =>
            {
                opts.LoginPath = new PathString("/account/AutoSignIn");
                opts.LogoutPath = ** TODO IF REQUIRED **
                opts.Cookie.Expiration = TimeSpan.FromHours(8);
            })
            .AddScheme<MyOptions, MyHandler>("AutoSignInScheme");

当用户尝试访问您的站点时,他将被重定向到自动登录控制器.然后从您的数据库中检索声明,将其存储在cookie中,并最终将用户重定向到他的初始目的地!.

When the users tries to access your site, he is redirected to the autosignin controller. Claims are then retrieved from your DB, stored in a cookie and the user is finally redirected to his initial destination!.

Seb