【问题标题】:Why is my Unauthorzied request not getting redirected to AccessDenied URL in ASP.Net MVC Core?为什么我的 Unauthorzied 请求没有被重定向到 ASP.Net MVC Core 中的 AccessDenied URL?
【发布时间】:2017-08-09 15:21:56
【问题描述】:

我有我的 AccountAdmin 控制器,用于管理身份中的用户。

所以我在控制器顶部有这样的授权属性:

[Authorize(Roles = "Admin")]
public class AccountAdminController : Controller

整个系统运行良好。如果我以具有管理员角色的用户身份登录,我可以访问该页面。如果我以没有管理员角色的用户身份登录,我将无法访问该页面。但我的问题是,我没有被重定向到“Account/AccessDenied”页面,而是得到了“/AccountAdmin/Index”URL,我被拒绝了内容,它只是给了我“状态代码:403;禁止”消息来自:

app.UseStatusCodePages();

在我的启动中。

在 StartUp.ConfigureServices 我有:

        services.AddIdentity<AppUser, IdentityRole>(options =>
        {
            options.Password.RequiredLength = 4;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireDigit = false;

            options.User.AllowedUserNameCharacters = null;
        }).AddEntityFrameworkStores<ApplicationDbContext>();

在 StartupConfigure 我有:

app.UseIdentity();

我知道我没有在这里发布很多代码,但这都是非常直接的东西。 需要注意的是我正在使用 Windows 身份验证。我在右上角显示用户登录名,例如 DomainName\UserName。 然后我做了一个模拟登录页面,我们可以在其中使用 TestRole1、TestRole2 等登录。

AccountController 如下所示:

public class AccountController : Controller
{
    private SignInManager<AppUser> _signInManager;
    private UserManager<AppUser> _userManager;
    public AccountController(SignInManager<AppUser> signInManager, 
        UserManager<AppUser> userManager)
    {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    public IActionResult Login()
    {
        return View(_userManager.Users.OrderBy(u => u.UserName));
    }

    [HttpPost]
    public async Task<IActionResult> Login(string userName, bool persistant)
    {
        await _signInManager.SignInAsync(await _userManager.FindByNameAsync(userName), persistant);
        return RedirectToAction("Index", "Home");
    }

    public async Task<IActionResult> LogOff()
    {
        await _signInManager.SignOutAsync();
        return RedirectToAction("Login", "Account");
    }

就身份验证和授权而言,一切运行良好。 接受 我发现在我单击登录之前,我的真实 Windows 帐户与我分配给自己的角色不匹配。它必须通过 SignInManager:

    [HttpPost]
    public async Task<IActionResult> Login(string userName, bool persistant)
    {
        await _signInManager.SignInAsync(await _userManager.FindByNameAsync(userName), persistant);
        return RedirectToAction("Index", "Home");
    }

我怎样才能让这个 AccessDenied 重定向工作?


更新 1:

我试着做一个这样的过滤器:

public class MyAuthorizationFilter : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (context.HttpContext.Response.StatusCode == 403)
        {
            context.HttpContext.Response.Redirect("/Access/Denied");
        }
    }
}

但是现在当我尝试用这个替换标准的授权属性时:

[MyAuthorizationFilter(Roles = "Admin")]

它不知道“角色”是什么。 它说:“找不到类型或命名空间角色。您是否缺少程序集或命名空间?”

【问题讨论】:

  • 我很想知道它options.Cookies.ApplicationCookie.AccessDeniedPath = "/Account/AccessDenied"; 可以与 Windows Auth 一起使用。我对此表示怀疑,但是……耸耸肩。
  • 试一试。没用。

标签: asp.net-core asp.net-identity asp.net-core-middleware


【解决方案1】:

好吧,我花了一段时间才弄清楚我想如何做到这一点。但在这里。 我不希望它经过错误处理,因为它不是未处理的错误。 它由 app.UseStatusCodePages(); 处理在 StartUp.Configure 中。

所以在 StartUp.Configure 的下面一行我添加:

// 400 - 599
app.UseStatusCodePagesWithRedirects("~/Account/Status/{0}");

这是一个我可以重定向的地方,以处理我想要对特定状态执行的操作,但为我未指定的内容保留默认值。

帐户控制器中的“帐户/状态”操作如下所示。

    public IActionResult Status()
    {
        string statusCode = HttpContext.Request.Path;
        statusCode = statusCode.Substring(statusCode.LastIndexOf('/') + 1);
        ViewBag.StatusCode = statusCode;
        return View(ViewBag);
    }

视图如下所示:

<div class="container-fluid">
    <div class="panel panel-danger">
        <div class="panel-header">
            <h3>StatusCode: 
                @switch ((string)ViewBag.StatusCode)
                {
                    case "403":
                        @:Access Denied
                        <div style="margin-top:5px"><a asp-controller="Account" asp-action="Login" class="btn btn-primary">Login as a different user</a></div>
                    break;
                default:
                        @ViewBag.StatusCode
                        break;
                }
            </h3>
        </div>
    </div>
</div>

我只是想让它在我插入它时不影响我的错误处理。那是不同的东西。

某处必须有一个简单的设置。但是我看到的这些解决方案都没有像 AuthenticatonChallenge = true 等等对我有用。 我认为现在这很整洁。

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2010-09-18
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多