【问题标题】:Authorization of user - Assigning user a Authorization Policy .Net Core 3.1用户授权 - 为用户分配授权策略 .Net Core 3.1
【发布时间】:2021-10-23 23:34:15
【问题描述】:

因此,当此代码运行时,用户获得了身份验证,我看到他们有我提供给他们的相关声明。但是,他们无权查看任何页面,因为他们没有正确的 AuthorizationPolicy。我认为给他们“Court User”的角色并对其进行身份验证会给他们默认的“Court_Users”AuthorizationPolicy,因为这符合要求,但它不能这样工作。

当用户通过身份验证后,如何为他们分配符合要求的授权策略?

启动页面:

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Shared/login";
        options.AccessDeniedPath = "/Shared/login";
    });
            services.AddRazorPages().AddRazorPagesOptions(options =>
            {
                options.Conventions.AuthorizeFolder("/NonCourt_Users","Non Court User");
                options.Conventions.AuthorizeFolder("/Court_Users","Court_Users");
                options.Conventions.AllowAnonymousToPage("/Shared");
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("Court_Users", new AuthorizationPolicyBuilder()
                                                .RequireAuthenticatedUser()
                                                .RequireClaim("role", "Court User")
                                                .Build());
                options.AddPolicy("NonCourt_Users", new AuthorizationPolicyBuilder()
                                                .RequireAuthenticatedUser()
                                                .RequireClaim("role", "Non Court User")
                                                .Build());
            });     

登录页面:

                         var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);

                            identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, User.EmailAddress));
                            identity.AddClaim(new Claim(ClaimTypes.Name, User.Name.First_Name));

                            if (User.CourtUser)
                            {
                                identity.AddClaim(new Claim(ClaimTypes.Role, "Court User"));
                            }
                            else
                            {
                                identity.AddClaim(new Claim(ClaimTypes.Role, "Non Court User"));
                            }
                            var principal = new ClaimsPrincipal(identity);

                            var authProperties = new AuthenticationProperties
                            {
                                AllowRefresh = true,
                                ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(60),
                                IsPersistent = true
                            };

                            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(principal), authProperties);

                            HttpContext.Session.SetObjectAsJson("CurrentUser", User);

                            clearSession();

【问题讨论】:

  • 如果您使用 IdentityServer4,则必须将您的 ApiScope 添加到策略中,然后将您的范围添加到声明中

标签: c# asp.net-core authentication razor authorization


【解决方案1】:
if (User.CourtUser)
{
    identity.AddClaim(new Claim(ClaimTypes.Role, "Court User"));
}
else
{
    identity.AddClaim(new Claim(ClaimTypes.Role, "Non Court User"));
}

正如 Gordon Khanh Ng 所说,在登录页面中,如果您使用 ClaimTypes.Role 类型添加声明,则在启动页面中,您应该使用相同的类型来设置策略,代码如下:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages(options =>
        {
            options.Conventions.AuthorizePage("/Contact");
            options.Conventions.AuthorizeFolder("/NonCourt_Users", "NonCourt_Users");
            options.Conventions.AuthorizeFolder("/Court_Users", "Court_Users");
        });

        #region snippet1
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
        #endregion
         
        services.AddAuthorization(options =>
        {
            options.AddPolicy("Court_Users", new AuthorizationPolicyBuilder()
                                            .RequireAuthenticatedUser()
                                            .RequireClaim(ClaimTypes.Role, "Court User")
                                            .Build());
            options.AddPolicy("NonCourt_Users", new AuthorizationPolicyBuilder()
                                            .RequireAuthenticatedUser()
                                            .RequireClaim(ClaimTypes.Role, "Non Court User")
                                            .Build());
        });
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

[注意]设置剃须刀页面约定时请注意策略名称。

那么,如果你想得到声明,你也应该使用相同的类型名称:

@page
@model CookieSample.Pages.Court_Users.CourtUserManageIndexModel
 
@using System.Security.Claims

@{ ViewData["Title"] = "Court User Manage Index"; }

<h2>@ViewData["Title"]</h2> 

<h2>@User.Claims.FirstOrDefault(c => c.Type == "FullName")?.Value</h2>
<h2>@User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role)?.Value</h2>

结果如下:

【讨论】:

  • 感谢您的澄清。我确实进行了更改,但这并没有为我解决问题。我仍然不明白,用户在哪里获得授权策略?他们仍然被锁定在页面之外,因为他们没有授权策略,即使他们符合它的标准?
  • 尝试删除`HttpContext.Session.SetObjectAsJson("CurrentUser", User); clearSession();` 在登录页面中。根据您的代码,您正在将您的应用程序设置为使用 cookie 身份验证,因此,登录成功后,用户身份信息(包括用户声明)将存储在 cookie 中,然后,在下一个请求中,您可以找到用户信息来自 HttpContext.User。请检查您的 Startup.cs 文件,您是否设置了 cookie/会话过期时间?确保它没有过期。
【解决方案2】:

如果我理解你的情况是正确的,那么这里一定有一些误解......

在登录页面上,您使用ClaimTypes.Role 设置cookie,它代表字符串http://schemas.microsoft.com/ws/2008/06/identity/claims/role。但在政策上,原来是RequireClaim("role", "Court User")...我想你可能想看看。

此外,如果您使用Authorize 属性,请务必指定相应的策略。那应该就好了。

【讨论】:

  • 我尝试将 RequireClaim("role", "Court User") 部分切换为大写的“Role”,但它没有改变任何东西。 options.Conventions.AuthorizeFolder("/Court_Users","Court_Users") 第二个参数指定需要哪个策略。您能否进一步详细说明,我不明白为什么这是不正确的。
  • 我的意思是你应该尝试RequireClaim(ClaimTypes.Role, "Court User"),而不仅仅是替换大写...ClaimTypes.Role 代表我上面提到的一个完整的差异字符串
猜你喜欢
  • 1970-01-01
  • 2020-02-16
  • 2020-09-19
  • 2016-05-20
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
相关资源
最近更新 更多