【问题标题】:How to set Claims from ASP.Net OpenID Connect OWIN components?如何从 ASP.Net OpenID Connect OWIN 组件中设置声明?
【发布时间】:2022-01-18 01:29:09
【问题描述】:

我对在身份验证管道期间添加新声明时使用新的 ASP.Net OpenID Connect 框架有疑问,如下面的代码所示。我不确定幕后到底发生了多少“魔法”。我认为我的大部分问题都围绕着对 OWIN 身份验证中间件了解不多,而不是 OpenID Connect。

第一季度。我应该从OwinContext.Authentication.User 手动设置HttpContext.Current.UserThread.CurrentPrincipal 吗?

第二季度。我希望能够像以前使用 System.IdentityModel.Claims.Claim 一样将对象类型添加到声明中。新的System.Security.Claims.Claim 类只接受字符串值?

第三季度。我是否需要在System.Security.Claims.CurrentPrincipal 中为我的ClaimsPrincipal 使用新的SessionSecurityToken 包装器来序列化为cookie - 我正在使用app.UseCookieAuthentication(new CookieAuthenticationOptions());,但现在确定在维护我在@ 期间添加的任何其他声明方面究竟做了什么987654330@活动?

    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    SecurityTokenValidated = (context) =>
                    {
                        // retriever caller data from the incoming principal
                        var UPN = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
                        var db = new SOSBIADPEntities();

                        var user = db.DomainUser.FirstOrDefault(b => (b.EntityName == UPN));

                        if (user == null)
                        {
                            // the caller was not a registered user - throw to block the authentication flow
                            throw new SecurityTokenValidationException();
                        }

                        var applicationUserIdentity = new ClaimsIdentity();
                        applicationUserIdentity.AddClaim(new Claim(ClaimTypes.Name, UPN, ""));
                        applicationUserIdentity.AddClaim(new Claim(ClaimTypes.Sid, user.ID.ToString(CultureInfo.InvariantCulture)));


                        var applications =
                            db.ApplicationUser
                            .Where(x => x.ApplicationChild != null && x.DomainUser.ID == user.ID)
                            .Select(x => x.ApplicationChild).OrderBy(x => x.SortOrder);

                        applications.ForEach(x =>
                            applicationUserIdentity.AddClaim(new Claim(ClaimTypes.System, x.ID.ToString(CultureInfo.InvariantCulture))));

                        context.OwinContext.Authentication.User.AddIdentity(applicationUserIdentity);

                        var hasOutlook = context.OwinContext.Authentication.User.HasClaim(ClaimTypes.System, "1");

                        hasOutlook = hasOutlook;

                        HttpContext.Current.User = context.OwinContext.Authentication.User;
                        Thread.CurrentPrincipal = context.OwinContext.Authentication.User;

                        var usr = HttpContext.Current.User;

                        var c =  System.Security.Claims.ClaimsPrincipal.Current.Claims.Count();


                        return Task.FromResult(0);
                    },
                }
            }
        );
    }

【问题讨论】:

    标签: c# asp.net authentication owin openid-connect


    【解决方案1】:

    您添加新的ClaimsIdentity 是否有特定原因?

    完成您的目标的最简单方法是检索通过验证传入令牌生成的ClaimsIdentity,一旦您拥有它,只需添加声明即可。其余的中间件将负责在会话 cookie 中序列化它以及其他所有内容,将结果放在当前的 ClaimsPrincipal 中,以及您似乎试图手动执行的所有其他事情。
    HTH
    五、

    【讨论】:

      【解决方案2】:

      执行令牌验证时,您可以使用新身份登录:

      private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> n)
      {
          var claimIdentity = new ClaimsIdentity(n.AuthenticationTicket.Identity);
          // Custom code...
          claimIdentity.Claims.Append(new Claim("TEST","1234"));
          n.OwinContext.Authentication.SignIn(claimIdentity);
          return Task.FromResult(0);
      }
      

      另一种选择直接进行分配,不适合我:

      private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> n)
      {
          var claimsPrincipal = new ClaimsPrincipal(n.AuthenticationTicket.Identity);
          // Custom code...
          // TEST:
          n.OwinContext.Response.Context.Authentication.User = claimsPrincipal;
          n.OwinContext.Request.User = claimsPrincipal;
          n.OwinContext.Authentication.User = claimsPrincipal;
          return Task.FromResult(0);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-09
        • 2016-05-15
        • 2022-12-17
        • 2019-08-24
        • 2020-11-19
        • 2019-09-11
        • 2019-05-18
        相关资源
        最近更新 更多