【问题标题】:How to read Claims from JWT Token .NET 4.5如何从 JWT Token .NET 4.5 读取声明
【发布时间】:2018-03-04 04:19:59
【问题描述】:

我无法从 Bearer JWT 令牌中读取令牌声明。登录正常,http 请求带有一个有效的 jwt 令牌到后端。 该应用程序自托管在 IIS7 上。 这是我在服务器端的代码:

SecurityConfig.cs

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/token"),
    AccessTokenExpireTimeSpan = TimeSpan.FromHours(24),
    Provider = new AuthorizationServerProvider() ,
    AccessTokenFormat = new JwtFormat(TimeSpan.FromHours(24))
});

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

AuthorizationServerProvider.cs

ClaimsIdentity id = new ClaimsIdentity(context.Options.AuthenticationType);

id.AddClaim(new Claim(InosysClaimTypes.UserId, Convert.ToString(appContext.UserId)));

id.AddClaim(new Claim(InosysClaimTypes.Username, context.UserName));
id.AddClaim(new Claim(InosysClaimTypes.Password, context.Password));

id.AddClaim(new Claim(InosysClaimTypes.FirNr, Convert.ToString(appContext.FirmenNummer)));
id.AddClaim(new Claim(InosysClaimTypes.FirNdl, Convert.ToString(appContext.Niederlassung)));
id.AddClaim(new Claim(InosysClaimTypes.Bereich, Convert.ToString(appContext.Bereich)));

id.AddClaim(new Claim(InosysClaimTypes.Sprache, Convert.ToString(appContext.Sprache)));
id.AddClaim(new Claim(InosysClaimTypes.SchiffNummern, appContext.SchiffNummern == null ? "" : string.Join(",", appContext.SchiffNummern)));
id.AddClaim(new Claim(InosysClaimTypes.Geschaeftsjahr, Convert.ToString(appContext.Geschaeftsjahr)));

var principal = new ClaimsPrincipal(id);
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
    HttpContext.Current.User = principal;
}

context.Validated(id);

在 ApiController 中,我尝试像这样获取调用者的有效负载信息:

ClaimsIdentity identity = User.Identity as ClaimsIdentity;

if (identity != null)
{
    appContext.UserId = Convert.ToInt32(identity.FindFirst(InosysClaimTypes.UserId).Value);
    appContext.Username = identity.FindFirst(InosysClaimTypes.Username).Value;
}

也就是被调试的身份变量: identity

【问题讨论】:

    标签: c# .net jwt bearer-token


    【解决方案1】:

    我只需要在 JWTFormat 类中实现 unprotect 函数

    public AuthenticationTicket Unprotect(string protectedText)
    {           
          try
          {
              var handler = new JwtSecurityTokenHandler();
    
              AppContext = new AppContext(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)
                        {
                            EventLogPriority = Properties.Settings.Default.EventLogPriority
                        };
    
              SecurityToken validToken;
    
              _validationParameters.IssuerSigningKey = new SymmetricSecurityKey(TextEncodings.Base64Url.Decode(Secret));
                        ClaimsPrincipal principal = handler.ValidateToken(protectedText, _validationParameters, out validToken);
    
               var validJwt = validToken as JwtSecurityToken;
    
               if (validJwt == null)
               {
                   throw new ArgumentException("Invalid JWT");
               }
    
               ClaimsIdentity identity = principal.Identities.FirstOrDefault();
               return new AuthenticationTicket(identity, new AuthenticationProperties());
         }            
         catch (SecurityTokenException ex)
         {
              var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Access Token is manipulated" };
                        throw new HttpResponseException(msg);
         }
    }
    

    【讨论】:

      【解决方案2】:

      我不知道您的 AuthorizationServerProvider.cs 出了什么问题, 但是从您在请求标头中提供 jwt 令牌的那一刻起,我认为它会以这种方式工作。

      我在每个接受 JWT 授权的控制器上使用 AuthorizeAttribute 处理标头,以设置请求的当前主体。

      public class JwtAuthentication : AuthorizeAttribute
      {
          protected override bool IsAuthorized(HttpActionContext actionContext)
          {
              var authHeader=actionContext.Request.Headers.Authorization;
              if (authHeader!=null&& !String.IsNullOrWhiteSpace(authHeader.Parameter))
                  System.Threading.Thread.CurrentPrincipal = JwtAuthenticationHandler.GetPrincipal(authHeader.Parameter);
              return ClientAuthorize.Authorize(Roles);
          }
      }
      

      用法

      [JwtAuthentication(Roles = "User")]
      public class ChatBotController : ApiController
      {}
      

      请注意,我在使用 Visual Studio 2017 从线程读取当前主体时遇到了一些问题。 如果您仍然遇到问题,您可能会看看。 ClaimsPrincipal.Current Visual Studio 2017 different behavior

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-12
        • 1970-01-01
        • 2021-07-20
        • 2021-02-26
        • 2019-11-11
        • 2022-01-09
        • 2015-09-14
        • 2017-02-13
        相关资源
        最近更新 更多