【发布时间】:2019-02-11 08:18:36
【问题描述】:
我有一个使用 Identity 2.0 的 ASP.NET Core 应用程序。我试图在用户未登录时返回 401 状态代码(或在他未授权时返回 403),但不同的函数仅返回 302 代码...
我根据我的应用需求进行了设置:
-
个性化的[授权]方法
[HttpPost] [RequiresPermission("Projects.Creation, Projects.Modification")] public IActionResult SaveProject(Project prj) { (...) {
我的 RequiresPermission 是一个继承 TypeFilterAttribute 的类,并且有一个似乎对设置不同返回结果很有用的函数:
public async Task OnResourceExecutionAsync(ResourceExecutingContext context,
ResourceExecutionDelegate next)
{
var principal = new CustomPrincipal(_PermissionProvider, context.HttpContext.User.Identity);
bool isInOneOfThisRole = false;
foreach (var item in _requiredPermissions.RequiredPermissions)
{
if (principal.IsInRole(item))
{
isInOneOfThisRole = true;
}
}
if (isInOneOfThisRole == false)
{
if (principal.Identity.IsAuthenticated)
{
context.Result = new UnauthorizedResult();
}
else
{
context.Result = new RedirectResult("~/Connexion/Login");
}
await context.Result.ExecuteResultAsync(context);
}
else
{
await next();
}
}
-
我的启动方法中的不同之处
services.AddIdentity<Utilisateur, Profil>().AddUserManager<CustomUserManager<Utilisateur>>().AddRoleManager<CustomRoleManager>().AddDefaultTokenProviders(); services.AddTransient<IUserStore<Utilisateur>, UserStore>(); services.AddTransient<IRoleStore<Profil>, ProfileStore>(); services.AddTransient<IPermissionProvider, PermissionProvider>(); services.Configure<IdentityOptions>(options => { // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; options.Lockout.AllowedForNewUsers = true; //options.SecurityStampValidationInterval = TimeSpan.FromHours(2); }); services.ConfigureApplicationCookie(options => { // Cookie settings options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(30); // If the LoginPath isn't set, ASP.NET Core defaults the path to /Account/Login. options.LoginPath = new PathString("/Connexion/Login"); options.LogoutPath = new PathString("/Connexion/SignedOut"); // If the AccessDeniedPath isn't set, ASP.NET Core defaults the path to /Account/AccessDenied. options.AccessDeniedPath = new PathString("/Connexion/AccessDenied"); options.SlidingExpiration = true; });
我已经尝试了很多建议,但似乎都没有这样的效果:
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
这个解决方案对我来说不是一个好的解决方案,因为它重定向了 ajax 和非 ajax 方法,这破坏了我的其他重定向......
我还尝试用我在网上找到的一个类来覆盖 AuthorizeAttribute 类。这个类似乎是我想要的,但它不适用于 ASP.Net Core...
using Microsoft.AspNetCore.Authorization;
using System.Net;
public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
var user = httpContext.User;
if (request.IsAjaxRequest())
{
if (user.Identity.IsAuthenticated == false)
response.StatusCode = (int)HttpStatusCode.Unauthorized;
else
response.StatusCode = (int)HttpStatusCode.Forbidden;
response.SuppressFormsAuthenticationRedirect = true;
response.End();
}
base.HandleUnauthorizedRequest(filterContext);
}
}
你有想法解决我的问题吗?或者我做错了什么。
【问题讨论】:
-
RequiresPermission属性如何工作?这是自定义属性吗? -
@Brad 编辑完成。我添加了我的 PermissionAttribute 类的主要功能。
标签: c# ajax asp.net-core asp.net-core-2.0 asp.net-identity-2