【问题标题】:Aspnetcore Bearer auth: Use user inside of middlewareAspnetcore Bearer auth:在中间件内部使用用户
【发布时间】:2018-12-30 22:21:47
【问题描述】:

我在我的应用程序中使用 cookie 和不记名身份验证。但我有奇怪的行为,我无法解释。

我确实有自定义中间件,我在其中向 Context.Items 添加了一些必需的数据。这一切都很好,但在那个中间件中,如果它的承载用户是空的,但当它的 cookie 时它就可以了。

   services
                .AddAuthorization(options =>
                {
                    options.DefaultPolicy = new AuthorizationPolicyBuilder()
                        .AddAuthenticationSchemes(OAuthValidationDefaults.AuthenticationScheme,
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            "Identity.Application")
                        .RequireAuthenticatedUser()
                        .Build();
                });
            //CookieAuthenticationDefaults.AuthenticationScheme
            services.AddAuthentication()
                .AddExternalAuthProviders(Configuration)
                .AddFlymarkOpenIdConnectServer()
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.LoginPath = "/Identity/Account/LogIn";
                    options.SlidingExpiration = true;
                    options.Events.OnRedirectToLogin = OnRedirectToLogin;
                })
                .AddOAuthValidation(OAuthValidationDefaults.AuthenticationScheme,
                    o=>o.Events.OnCreateTicket = OnCreateTicket);
            services.ConfigureApplicationCookie(config =>
            {
                config.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = OnRedirectToLogin
                };
            });

我在 CreateTicket 上使用的临时解决了我的问题

   private async Task OnCreateTicket(CreateTicketContext arg)
        {
            if (arg.HttpContext.Items[FlymarkWeb.CurrentUserKey] == null && arg.Identity.IsAuthenticated)
            {
                var db= (FlymarkContext) arg.HttpContext.RequestServices.GetService(typeof(FlymarkContext));
                arg.HttpContext.Items[FlymarkWeb.CurrentUserKey] =
                    await db.Users.FirstOrDefaultAsync(u => u.Id == arg.Identity.GetUserId());
            }
        }

和中间件

  public async Task Invoke(HttpContext httpContext, FlymarkContext context, DomainService _sourceDomainService)
        {
            if (httpContext.Items[FlymarkWeb.CurrentUserKey] == null)
            {
                httpContext.Items[FlymarkWeb.CurrentUserKey] = httpContext.User.Identity.IsAuthenticated
                    ? await context.Users.FirstOrDefaultAsync(u => u.Id == httpContext.User.GetUserId())
                    : null;
            }
....
}

所以我的问题是为什么 cookie 和 oauth 不同?为什么如果它的 cookie 我可以访问中间件中的用户而它的 oauth 我不能?

【问题讨论】:

    标签: asp.net-core oauth middleware


    【解决方案1】:

    这是因为当您调用 services.AddIdentity() 时,ASP.NET Core 标识 registers itself as the default authentication scheme handler

    当接收到请求时,app.UseAuthentication() 后面的中间件会自动调用 Identity 注册的 cookie 身份验证处理程序,并使用从身份验证 cookie 中提取的结果 ClaimsPrincipal 填充 HttpContext.User

    使用不记名令牌时不会发生这种情况,因为 OAuth 验证处理程序不会将自己注册为默认身份验证处理程序(在 2.0 中,您必须手动明确地执行此操作)。

    要将其配置为默认处理程序,您可以这样做:

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = OAuthValidationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OAuthValidationDefaults.AuthenticationScheme;
    });
    

    或者,您可以直接自己执行身份验证操作,而不是依赖HttpContext.User。例如:

    public async Task Invoke(HttpContext httpContext, FlymarkContext context, DomainService _sourceDomainService)
    {
        if (httpContext.Items[FlymarkWeb.CurrentUserKey] == null)
        {
            var principal = (await httpContext.AuthenticateAsync(OAuthValidationDefaults.AuthenticationScheme))?.Principal;
    
            httpContext.Items[FlymarkWeb.CurrentUserKey] = principal?.Identity != null && principal.Identity.IsAuthenticated
                ? await context.Users.FirstOrDefaultAsync(u => u.Id == principal.GetUserId())
                : null;
        }
    }
    

    【讨论】:

    • 据我了解,我的 .AddCookie 没有任何作用,基本上我只需要使用 ConfigureApplicationCookie 来更改登录页面和事件,对吗?
    • 是的,绝对的。
    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 2023-02-20
    • 1970-01-01
    • 2015-06-29
    • 2014-11-03
    • 2015-11-16
    • 1970-01-01
    • 2021-07-10
    相关资源
    最近更新 更多