gpt4 book ai didi

c# - 使用 cookie 身份验证的 ASP.NET Core 2.0 自定义中间件

转载 作者:行者123 更新时间:2023-12-05 00:14:24 24 4
gpt4 key购买 nike

我需要为我的公司实现自定义“身份验证”。
我在引号中这么说是因为从技术上讲,用户在访问应用程序之前已通过身份验证,如果是这样,则 userId 将存在于请求 header 中。

我需要做的是找出一种方法来查询数据库并根据该 Id 获取其他用户信息,并设置 HttpContext.User 对象,以便它可以在应用程序中轻松使用。

我现在采取的路线涉及使用没有 ASP.NET Core Identity 的 Cookie 身份验证。我将这个想法与自定义中间件相结合,该中间件将为用户查询数据库,从 db 字段填充 Claims,并使用 context.SignInAsync 创建 cookie。我把这个中间件放在 app.UseAuthentication() 之前。问题是在第一次请求时没有设置 .User 对象,因为 SignIn 方法似乎只创建了 cookie 而没有设置 .User 对象。身份验证中间件还没有看到 cookie,因为它在第一次请求时不存在。

任何人都可以提供任何想法吗?也许我做错了,或者这种技术很好,但我错过了让它工作所需的东西。

在 Startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();


services.AddAuthentication("MyAuthenticationCookie")
.AddCookie("MyAuthenticationCookie");
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}

app.UseStaticFiles();

app.UseMyUserMiddleware();

app.UseAuthentication();

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

自定义中间件:
    public class MyUserMiddleware
{
private readonly RequestDelegate _next;

public MyUserMiddleware(RequestDelegate next)
{
_next = next;
}

public Task Invoke(HttpContext context)
{
// Sign in user if this auth cookie doesn't exist
if (context.Request.Cookies[".AspNetCore.MyAuthenticationCookie"] == null)
{
// Get user from db - not done

// Set claims from user object - put in dummy test name for now
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "TEST"),

};

var claimsIdentity = new ClaimsIdentity(claims, "MyAuthenticationCookie");

context.SignInAsync("MyAuthenticationCookie", new ClaimsPrincipal(claimsIdentity));
}

return this._next(context);
}
}

public static class MyUserMiddlewareExtensions
{
public static IApplicationBuilder UseMyUserMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyUserMiddleware>();
}
}

最佳答案

简答 :您应该使用自定义 AuthorizationHandler验证和检索声明。

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

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

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 中间件会在必要时调用它:
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var authorization = Request.Headers["UserId"].ToString();
(...)
return AuthenticateResult.Success(
new AuthenticationTicket(**your claims**, Scheme.Name));
}

此方法返回的声明将通过 HttpContext.User 对象可用。

完成后,您需要将您的方案添加到身份验证构建器。
services.AddAuthentication()
.AddCookie("MyAuthenticationCookie");
.AddScheme<MyOptions, MyHandler>("MyHandlerName");

不要忘记在 Startup.cs/Configure 方法中添加以下代码行
 app.UseAuthentication();

最后,您需要在要保护的所有类/方法上添加 Authorize 属性
[Authorize(AuthenticationSchemes = "MyHandlerName")]
public class MyControllerController : BaseController
{ }

OR

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

编辑:这里的解决方案涵盖了完整的登录过程。
让我们考虑定义两个身份验证方案
- 基于 Cookie 的称为 CookieScheme
- AutoSignInScheme:按照上述步骤创建相应的处理程序
[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 中,添加以下几行:
       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");

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

塞伯

关于c# - 使用 cookie 身份验证的 ASP.NET Core 2.0 自定义中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46938511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com