首页 > 解决方案 > 如何使用来自“外部登录”的声明向 razor PageModel 的“ClaimsPrincipal User”添加声明身份

问题描述

在我们的 razor 页面的帖子中,我们调用了一个 Api 方法来登录用户,这个 Api 方法返回一个带有一些声明的 JTW。登录成功后,我们尝试将此声明放在基类的User属性上PageModel,但是当我们尝试在另一个页面上访问此声明时,此声明不再可用。

来自 PageModel 的用户属性

方法:

public async Task<IActionResult> OnPostAsync()
{
    var jwtToken = await _externalApi.Execute<string>($"/auth/", Method.POST, jsonBody: myCredentialsObject);

    var handler = new JwtSecurityTokenHandler();
    var securityToken = handler.ReadJwtToken(jwtToken);

    User.AddIdentity(new ClaimsIdentity(securityToken.Claims, "myClaims"));

    Response.Cookies.Append("bearer", jwtToken);

    return LocalRedirect("/user/index");

    return Page();
}

登录页面:

登录页面的 OnPost

另一个页面:

OnGet 在另一个页面上

每次http请求后“重置”User属性?这种方法可行吗?

标签: razorjwtidentityrazor-pages

解决方案


经过一番研究,在这种情况下,我们需要创建一个新的ClaimsPrincipal并“重写”auth cookie,HttpContext.SignInAsync(...)方法是应用新ClaimsPrincipalservices.AddAuthentication(...)中间件可以User为我们设置属性。

像这样的东西:

启动类:

public class Startup
{
   // Omitted for brevity...
   public void ConfigureServices(IServiceCollection services)
   {
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, cookieAuthOptions =>
                {
                    cookieAuthOptions.Cookie.Name = "MyApplicationCookie";
                    cookieAuthOptions.LoginPath = "/signIn";
                    cookieAuthOptions.LogoutPath = "/signOut";
                    cookieAuthOptions.AccessDeniedPath = "/accessDenied";
                });
   }

   public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
   {
       // Omitted for brevity...
       app.UseAuthentication();
   }
}

登录页面:

public async Task<IActionResult> OnPostAsync()
{
    var signinResult = await _aiguiApi.Execute<string>($"/auth/", Method.POST, jsonBody: SignInInputModel);

    var jwt = signinResult.Value.ToString();
    var handler = new JwtSecurityTokenHandler();
    var token = handler.ReadJwtToken(jwt);

    // THIS CODE HERE, MAKE THE "MAGIC"...
    var userPrincipal = new ClaimsPrincipal(
        new ClaimsIdentity(token.Claims, "myClaims")
    );
    await HttpContext.SignInAsync(userPrincipal);
    //...

    Response.Cookies.Append("bearer", jwt);

    return LocalRedirect("/user/index");

    return Page();
}

设置

另一个页面:

另一个可以访问用户属性的页面

就是这样,伙计们!


推荐阅读