【问题标题】:User is not authenticated in Middleware, but authenticated in Controller用户未在中间件中进行身份验证,但在控制器中进行身份验证
【发布时间】:2020-11-05 22:43:15
【问题描述】:

我正在使用OpenIddict 包来处理我的.net core Api 应用程序中的身份验证。在我的控制器中,我可以看到用户、它的声明、角色等。但是在中间件中,我无权访问用户,就好像用户没有经过身份验证一样。

我认为我在ConfigureServicesStartup.cs 中的Configure 方法中遗漏了一些东西。

public void ConfigureServices(IServiceCollection services)
        {

            // Add framework services.
            services.AddMvc(
                    config =>
                    {
                        //We are adding a default policy required for all requests
                        var policyBuilder =
                            new AuthorizationPolicyBuilder(OpenIddictValidationDefaults.AuthenticationScheme);
                        
                        var policy = policyBuilder.RequireAuthenticatedUser()
                            .Build();
                        config.Filters.Add(new AuthorizeFilter(policy));
                    }
                );


            services.AddDbContext<TGDbContext>((ctx, options) =>
            {
                options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
                options.UseOpenIddict();
            }, ServiceLifetime.Scoped, ServiceLifetime.Scoped);

            
            // Register the OpenIddict services.
            services.AddOpenIddict()
                .AddCore(options =>
                {
                    options.UseEntityFrameworkCore()
                        .UseDbContext<TGDbContext>();
                })
                .AddServer(options =>
                {
                    options.UseMvc();
                    options.EnableTokenEndpoint( "/connect/token");
                    options.AllowPasswordFlow();
                    options.AllowRefreshTokenFlow();
                    options.AcceptAnonymousClients();
                    options.AllowCustomFlow("GuestLogin");
                    options.RegisterScopes("Booking");
                    if (this._env.IsDevelopment())
                        options.DisableHttpsRequirement(); // Note: Requires Https in production
                    options.RegisterScopes(
                        OpenIdConnectConstants.Scopes.OpenId,
                        OpenIdConnectConstants.Scopes.Email,
                        OpenIdConnectConstants.Scopes.Phone,
                        OpenIdConnectConstants.Scopes.Profile,
                        OpenIdConnectConstants.Scopes.OfflineAccess,
                        OpenIddictConstants.Scopes.Roles);
                })
                .AddValidation();

            // add identity
            services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddEntityFrameworkStores<TGDbContext>()
                .AddDefaultTokenProviders();

            // Configure Identity options and password complexity here
            services.Configure<IdentityOptions>(options =>
            {
                // User settings
                options.User.RequireUniqueEmail = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireLowercase = false;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy(.....);
             ....
             ....
             ....           
            });
  .....
  .....
  .....

}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ....
            ....
            ....

            app.UseAuthentication();

            app.Use(async (context, next) =>
            {
                var isAuthenticated = context.User.Identity.IsAuthenticated;
                // isAuthenticated is false here
                // also context.User.Claims is empty
                Console.WriteLine(isAuthenticated);
                await next.Invoke();
            });

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

我使用OpenIddict 2.0.1OpenIddict.EntityFramework 2.0.1 定位.Net Core 2.2

【问题讨论】:

    标签: .net-core openiddict


    【解决方案1】:

    您看到的行为是预期的(并非特定于 OpenIddict):通过注册一个指向 OpenIddict 验证处理程序的 AuthorizeFilter,您只是将 MVC 配置为验证不记名令牌,而不是您的应用程序的其余部分,包括中间件。

    要将 OpenIddict 配置为默认身份验证方案,请调用

    services.AddAuthentication(options =>
    {
        // When targeting OpenIddict 3.0, OpenIddictValidationAspNetCoreDefaults
        // must be used instead of OpenIddictValidationDefaults.
        options.DefaultAuthenticateScheme = OpenIddictValidationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIddictValidationDefaults.AuthenticationScheme;
    });
    

    【讨论】:

    • 谢谢凯文;你的意思是services.AddAuthentication?我添加了这个(即 services.AddAuthentication),但中间件中仍然没有用户。我也需要修改services.AddMVC吗?
    • 是的,services.AddAuthentication()。您是否发送了有效的访问令牌? app.UseMvc() 是否正确添加在内联中间件之后?
    • 我已经编辑了我的问题以包括 app.UseMvc 一块。
    猜你喜欢
    • 2015-09-23
    • 2021-10-23
    • 2010-11-11
    • 2013-03-11
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 2018-07-01
    • 2021-06-11
    相关资源
    最近更新 更多