实现 AbpIdentity cookies 和 JwtBearer

我继承了一个同时使用 Web API 和 MVC 前端的 ASPnetzero 应用程序。API 通过 Bearer 进行身份验证,前端通过 AbpIdentity (Cookies) 进行身份验证。几天前,我勇敢地决定更新我的 nuGet 软件包。该更新伴随着从 .netCore v1 到 v2 的升级。但在 JwtBearer 中间件过时后,我在身份验证方面遇到了一些困难。我可以使用 cookie 进行身份验证,但不能使用不记名令牌。


我几乎尝试了一切。使用多种身份验证方法意味着一次只能使用一种方法。


在 Startup.cs 中,我有以下内容(片段):


public IServiceProvider ConfigureServices(IServiceCollection services)

        {

            services.AddAbpIdentity<Tenant, User, Role>()

            .AddUserManager<UserManager>()

            .AddRoleManager<RoleManager>()

            .AddSignInManager<SignInManager>()

            .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory>()

            .AddDefaultTokenProviders();

        }

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

        {

          AuthConfigurer.Configure(app, _appConfiguration);

         }

然而,这是一个自我回答的问题,我希望我能帮助任何有类似或相同情况的人,因为我已经整理了自己的解决方案。这个想法是让应用程序使用 Bearer 令牌(仅当使用 API 时)和 cookie(仅当使用 MVC 时)。


我还面临一个挑战,因为 MVC 对 API 进行 XHR 调用以获取要在前端显示的数据。这意味着 API 还需要与 Cookie 配合使用(但仅适用于 MVC 用户)。


慕桂英3389331
浏览 72回答 1
1回答

红糖糍粑

所以我终于弄清楚了,这需要相当大的转变。结果是:API 用户仅使用 Bearer Token 进行身份验证MVC 用户使用 Cookie 进行身份验证,登录后应用程序中的 API 调用也使用相同的身份验证。所有更改都是在 Startup.cs 中进行的,我还注释掉了对 AuthConfigure.cs 文件的引用,该文件现已过时。我愿意接受对该解决方案的任何改进或建议。Startup.cs 文件中的重要部分:public IServiceProvider ConfigureServices(IServiceCollection services)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; services.AddAuthentication()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddJwtBearer(cfg =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cfg.RequireHttpsMetadata = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cfg.SaveToken = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cfg.TokenValidationParameters = new TokenValidationParameters()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The application URL is used for the Issuer and Audience and is included in the appsettings.json&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ValidIssuer = _appConfiguration["Authentication:JwtBearer:Issuer"],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ValidAudience = _appConfiguration["Authentication:JwtBearer:Audience"],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appConfiguration["Authentication:JwtBearer:SecurityKey"]))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Activate Cookie Authentication without Identity, since Abp already implements Identity below.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/Login");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Add the Authentication Scheme Provider which will set the authentication method based on the kind of request. i.e API or MVC&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; services.AddSingleton<IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Some of these extensions changed&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;services.AddAbpIdentity<Tenant, User, Role>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddUserManager<UserManager>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddRoleManager<RoleManager>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddSignInManager<SignInManager>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddDefaultTokenProviders();//…}public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)&nbsp; &nbsp; &nbsp; &nbsp; {// app.UseAuthentication is critical here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseAuthentication();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseAbp(); //Initializes ABP framework.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseCors("CorsPolicy");//…&nbsp;//AuthConfigurer.Configure(app, _appConfiguration);//…&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}}public class CustomAuthenticationSchemeProvider : AuthenticationSchemeProvider{&nbsp; &nbsp; private readonly IHttpContextAccessor httpContextAccessor;&nbsp; &nbsp; public CustomAuthenticationSchemeProvider(&nbsp; &nbsp; &nbsp; &nbsp; IHttpContextAccessor httpContextAccessor,&nbsp; &nbsp; &nbsp; &nbsp; IOptions<AuthenticationOptions> options)&nbsp; &nbsp; &nbsp; &nbsp; : base(options)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this.httpContextAccessor = httpContextAccessor;&nbsp; &nbsp; }&nbsp; &nbsp; private async Task<AuthenticationScheme> GetRequestSchemeAsync()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var request = httpContextAccessor.HttpContext?.Request;&nbsp; &nbsp; &nbsp; &nbsp; if (request == null)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentNullException("The HTTP request cannot be retrieved.");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // For API requests, use authentication tokens.&nbsp; &nbsp; &nbsp; &nbsp; var authHeader = httpContextAccessor.HttpContext.Request.Headers["Authorization"].FirstOrDefault();&nbsp; &nbsp; &nbsp; &nbsp; if (authHeader?.StartsWith("Bearer ") == true)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return await GetSchemeAsync(JwtBearerDefaults.AuthenticationScheme);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // For the other requests, return null to let the base methods&nbsp; &nbsp; &nbsp; &nbsp; // decide what's the best scheme based on the default schemes&nbsp; &nbsp; &nbsp; &nbsp; // configured in the global authentication options.&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; public override async Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync() =>&nbsp; &nbsp; &nbsp; &nbsp; await GetRequestSchemeAsync() ??&nbsp; &nbsp; &nbsp; &nbsp; await base.GetDefaultAuthenticateSchemeAsync();&nbsp; &nbsp; public override async Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync() =>&nbsp; &nbsp; &nbsp; &nbsp; await GetRequestSchemeAsync() ??&nbsp; &nbsp; &nbsp; &nbsp; await base.GetDefaultChallengeSchemeAsync();&nbsp; &nbsp; public override async Task<AuthenticationScheme> GetDefaultForbidSchemeAsync() =>&nbsp; &nbsp; &nbsp; &nbsp; await GetRequestSchemeAsync() ??&nbsp; &nbsp; &nbsp; &nbsp; await base.GetDefaultForbidSchemeAsync();&nbsp; &nbsp; public override async Task<AuthenticationScheme> GetDefaultSignInSchemeAsync() =>&nbsp; &nbsp; &nbsp; &nbsp; await GetRequestSchemeAsync() ??&nbsp; &nbsp; &nbsp; &nbsp; await base.GetDefaultSignInSchemeAsync();&nbsp; &nbsp; public override async Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync() =>&nbsp; &nbsp; &nbsp; &nbsp; await GetRequestSchemeAsync() ??&nbsp; &nbsp; &nbsp; &nbsp; await base.GetDefaultSignOutSchemeAsync();}
打开App,查看更多内容
随时随地看视频慕课网APP