Joã*_*iva 0 asp.net-identity openid-connect .net-core asp.net-core identityserver4
使用 .NET Core 3.1 框架,我尝试使用以下设置配置 Web 平台:
所有这三个组件(Razor Pages + Angular + Identity Server)都捆绑到一个 .NET Core Web 项目中。我还搭建了 Identity 框架,以便能够自定义页面的外观和行为。
我几乎能够按照我想要的方式配置应用程序,方法是基本上混合 Razor Pages 选项的启动模板代码(用户帐户存储在本地)和 Angular 模板选项(用户帐户存储在本地)以及一些尝试、错误和调查。
我的申请目前的状态是:
本地主机:5001/Dashboard(Angular SPA 主路由)
/Identity(仅用于带有身份的页面),则 cookie 似乎不再包含正确的信息,并且我在这些路由中没有会话。这意味着,例如,如果我使用SignInManager.IsSignedIn(User)仅显示受 保护的管理页面的导航选项options.Conventions.AuthorizePage($"/Administration"),如果我位于具有身份路由的 URL 中,则将显示导航选项卡,否则将显示不显示:本地主机:5001/身份/帐户/登录
localhost:5001(Razor Pages 应用程序主路由)
/Identity,如果单击它,我也会收到 401 未经授权的错误,因为“管理”页面前面没有该/Identity路由:本地主机:5001/管理
我已设法将问题追溯到AddIdentityServerJwt(). 如果没有这个,Razor Pages 应用程序的登录将按预期工作,但我显然无法在之后使用 Angular 应用程序进行身份验证和授权。
我去检查该方法的源代码,结果发现它创建了一个新的IdentityServerJwtPolicySchemeForwardSelector方法,将 JWT 策略方案转发到该方案DefaultIdentityUIPathPrefix,正如您可能已经猜到的那样,该方案仅包含值"/Identity"。
我通过以下方式配置了我的 Startup 类:
启动.cs
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services
.AddDbContext<ApplicationDbContext>(optionsBuilder =>
{
DatabaseProviderFactory
.CreateDatabaseProvider(configuration, optionsBuilder);
});
services
.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services
.AddIdentityServer()
.AddApiAuthorization<IdentityUser, ApplicationDbContext>();
services
.AddAuthentication()
.AddIdentityServerJwt();
services
.AddControllersWithViews();
services
.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizePage($"/Administration");
});
services
.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddTransient<IEmailSender, EmailSenderService>();
services.Configure<AuthMessageSenderOptions>(configuration);
services.AddTransient<IProfileService, ProfileService>();
}
public void Configure(IApplicationBuilder applicationBuilder, IWebHostEnvironment webHostEnvironment)
{
SeedData.SeedDatabase(applicationBuilder, configuration);
if (webHostEnvironment.IsDevelopment())
{
applicationBuilder.UseDeveloperExceptionPage();
applicationBuilder.UseDatabaseErrorPage();
}
else
{
applicationBuilder.UseExceptionHandler("/Error");
applicationBuilder.UseHsts();
}
applicationBuilder.UseHttpsRedirection();
applicationBuilder.UseStaticFiles();
applicationBuilder.UseCookiePolicy();
if (!webHostEnvironment.IsDevelopment())
{
applicationBuilder.UseSpaStaticFiles();
}
applicationBuilder.UseRouting();
applicationBuilder.UseAuthentication();
applicationBuilder.UseIdentityServer();
applicationBuilder.UseAuthorization();
applicationBuilder.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
applicationBuilder.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (webHostEnvironment.IsDevelopment())
{
if (bool.Parse(configuration["DevelopmentConfigurations:UseProxyToSpaDevelopmentServer"]))
{
spa.UseProxyToSpaDevelopmentServer(configuration["DevelopmentConfigurations:ProxyToSpaDevelopmentServerAddress"]);
}
else
{
spa.UseAngularCliServer(npmScript: configuration["DevelopmentConfigurations:AngularCliServerNpmScript"]);
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
如何配置我的应用程序,以便会话在整个应用程序中可用,而不仅仅是在具有“/Identity”路由的 URL 上可用,同时维护 Razor Pages 应用程序和 Angular 应用程序的身份验证和授权?
我遇到了同样的问题,并通过添加我自己的 PolicyScheme 来解决它,该 PolicyScheme 根据请求路径决定应该使用哪种类型的身份验证。我所有的 razor 页面都有一个以“/Identity”或“/Server”开头的路径,所有其他请求都应该使用 JWT。
我使用以下编码在 ConfigureServices 中进行了设置:
// Add authentication using JWT and add a policy scheme to decide which type of authentication should be used
services.AddAuthentication()
.AddIdentityServerJwt()
.AddPolicyScheme("ApplicationDefinedAuthentication", null, options =>
{
options.ForwardDefaultSelector = (context) =>
{
if (context.Request.Path.StartsWithSegments(new PathString("/Identity"), StringComparison.OrdinalIgnoreCase) ||
context.Request.Path.StartsWithSegments(new PathString("/Server"), StringComparison.OrdinalIgnoreCase))
return IdentityConstants.ApplicationScheme;
else
return IdentityServerJwtConstants.IdentityServerJwtBearerScheme;
};
});
// Use own policy scheme instead of default policy scheme that was set in method AddIdentityServerJwt
services.Configure<AuthenticationOptions>(options => options.DefaultScheme = "ApplicationDefinedAuthentication");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
691 次 |
| 最近记录: |