.net - 从 .net core 2.2 迁移到 3.0 => 在 Authenticaton 之前执行授权
问题描述
几天前,我决定将我的应用程序从 .net core 2.2 迁移到 .net core 3.0 我面临的问题是,尽管按照中间件迁移的官方文档以正确的顺序订购了 app.Use..授权发生在认证之前。
这是我在 Startup 类中的 ConfigureServices 方法:
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(settings.AppInsightsConnection);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSingleton(Log.Logger);
services.AddSingleton(settings);
services.AddHttpContextAccessor();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options => options.AccessDeniedPath = "/users/denied")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = settings.Authority;
options.ClientId = settings.ClientId;
options.ClientSecret = settings.ClientSecret;
options.ResponseType = "code";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.SignedOutRedirectUri = settings.PostLogoutUri;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("ccms");
options.Scope.Add("profile");
options.ClaimActions.Remove("amr");
options.ClaimActions.Remove("auth_time");
options.ClaimActions.MapUniqueJsonKey("website", "website");
options.ClaimActions.Add(new MapAllClaimsAction());
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
};
options.Events = new OpenIdConnectEvents
{
OnRemoteFailure = context =>
{
context.HandleResponse();
context.Response.Redirect("/Login");
return Task.FromResult(0);
},
};
options.Events.OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.Prompt = "login";
return Task.CompletedTask;
};
});
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
services.AddMvc(config =>
{
config.EnableEndpointRouting = false;
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
config.Filters.Add(new AuthorizeFilter(policy));
config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); // it validates all of requests, except for GET requests
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddAuthorization(options =>
{
options.AddPolicy("Permissions", policy =>
{
policy.RequireAssertion(context => PermissionGranted(context));
});
});
}
这是配置方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
await next();
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=Index}/{id?}");
});
}
我正在使用 Microsoft.AspNetCore.Authentication.OpenIdConnect -vERSION 3.0.0 进行身份验证和授权的自定义策略。如果我在控制器上使用 [Authorize(Permissions)],这是在用户完全通过身份验证之前获得的方法:
private bool PermissionGranted(AuthorizationHandlerContext context)
{
var result = false;
var httpContext = contextAccessor.HttpContext;
var request = httpContext.Request;
var requestPath = request.Path.Value.ToLower();
var method = request.Method.ToLower();
var relativePath = requestPath;
var dbContext = new PasswordManagerContext(settings.ConnectionString);
var userParameters = Helper.GetUserParameters(httpContext, Log.Logger, settings).Result;
var allUrls = dbContext.PathAccess.ToList();
var rolePermissions = dbContext.RolePermissions.ToList();
var user = dbContext.Users.FirstOrDefault(x => x.Ccmsid == userParameters.CcmsId);
var regexPath = new Regex(@"\d$");
if (regexPath.IsMatch(relativePath))
{
relativePath = Regex.Replace(relativePath, @"[\d-]", string.Empty);
}
var pathAccess = allUrls.FirstOrDefault(x => x.RelativeUrl == relativePath && x.Method == method);
if (pathAccess != null)
result = dbContext.RolePermissions.Any(x => x.RoleId == user.RoleId && x.PathAccessId == pathAccess.Id);
return result;
}
这个授权-身份验证部分在 .net core 2.2 中运行良好 我在配置中做错了吗?任何帮助表示赞赏!
解决方案
推荐阅读
- java - matlab no java模式下打开串口
- javascript - 在 JavaScript 中访问 Struts 2 变量
- linux - 尝试在 Ubuntu 中使用 Wine 运行 Windows 应用程序时缺少 mfc140u.dll
- office365 - O365 OWA 回复或回复所有视图模型或操作
- excel - SetWindowPos 不适用于某些程序
- javascript - Javascript Easing 无法正常工作 - EaseInCirc?
- android - Flutter - 首次构建时出现 FutureBuilder 错误
- c - 格式“%s”需要“*char”类型的参数,但参数 2 的类型为“int”
- ios - 如何使用可解码解析包含动态键的 JSON?
- spring - Spring boot JPA 多对多,带有额外的列插入和更新问题