【问题标题】:Manually decode OAuth bearer token in c#在 C# 中手动解码 OAuth 不记名令牌
【发布时间】:2017-04-09 13:47:02
【问题描述】:

在我的基于 Web Api 2.2 OWIN 的应用程序中,我遇到了一种情况,我需要手动解码承载令牌,但我不知道该怎么做。 这是我的startup.cs

public class Startup
{
    public static OAuthAuthorizationServerOptions OAuthServerOptions { get; private set; }
    public static UnityContainer IoC;
    public void Configuration(IAppBuilder app)
    {
        //Set Auth configuration
        ConfigureOAuth(app);

        ....and other stuff
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new AuthProvider(IoC.Resolve<IUserService>(), IoC.Resolve<IAppSettings>())
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

在我的控制器中,我将不记名令牌作为参数发送

[RoutePrefix("api/EP")]
public class EPController : MasterController
{
    [HttpGet]
    [AllowAnonymous]
    [Route("DC")]
    public async Task<HttpResponseMessage> GetDC(string token)
    {
        //Get the claim identity from the token here
        //Startup.OAuthServerOptions...

        //..and other stuff
    }
}

如何手动解码并从作为参数传递的令牌中获取声明?

注意:我知道我可以在标头中发送令牌并使用 [Authorize] 和 (ClaimsIdentity)User.Identity 等,但问题是当令牌中没有出现时如何读取令牌标题。

【问题讨论】:

    标签: c# asp.net-web-api oauth-2.0 owin bearer-token


    【解决方案1】:

    仅将其放在这里以供将来可能访问的其他人使用。在https://long2know.com/2015/05/decrypting-owin-authentication-ticket/ 找到的解决方案更简单。

    只有 2 行:

    var secureDataFormat = new TicketDataFormat(new MachineKeyProtector());
    AuthenticationTicket ticket = secureDataFormat.Unprotect(accessToken);
    
    
    
    private class MachineKeyProtector : IDataProtector {
        private readonly string[] _purpose =
        {
            typeof(OAuthAuthorizationServerMiddleware).Namespace,
            "Access_Token",
            "v1"
        };
    
        public byte[] Protect(byte[] userData)
        {
            throw new NotImplementedException();
        }
    
        public byte[] Unprotect(byte[] protectedData)
        {
            return System.Web.Security.MachineKey.Unprotect(protectedData, _purpose);
        } }
    

    【讨论】:

    • 尽管我没有测试这个解决方案,但我认为你花时间在一个封闭的问题上分享你的解决方案真是太好了 +1
    【解决方案2】:

    我创建了一个用于反序列化不记名令牌的示例项目,这些不记名令牌使用 MachineKeyDataProtector 进行加密。 你可以看看源代码。

    Bearer-Token-Deserializer

    【讨论】:

    【解决方案3】:

    您可以使用 System.IdentityModel.Tokens.Jwt 包读取 JWT 并创建 Principals 和 Identity 对象 - https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/

    这是一个简单的示例,显示了读取和验证令牌时可用的选项,

        private ClaimsIdentity GetIdentityFromToken(string token, X509Certificate2 certificate)
        {  
            var tokenDecoder = new JwtSecurityTokenHandler();         
            var jwtSecurityToken = (JwtSecurityToken)tokenDecoder.ReadToken(token);
    
            SecurityToken validatedToken;
    
            var principal = tokenDecoder.ValidateToken(
                jwtSecurityToken.RawData,
                new TokenValidationParameters()
                    {
                        ValidateActor = false,
                        ValidateIssuer = false,
                        ValidateAudience = false,
                        ValidateLifetime = false,
                        ValidateIssuerSigningKey = false,
                        RequireExpirationTime = false,
                        RequireSignedTokens = false,
                        IssuerSigningToken = new X509SecurityToken(certificate)
                    },
                out validatedToken);
    
            return principal.Identities.FirstOrDefault();
        }
    

    【讨论】:

    • asp.net 身份中的不记名令牌不是 jwt 令牌。 jwt 令牌应如下所示:header.payload.signature。我得到的不记名令牌不包含点并且它不是 base64 编码的。
    猜你喜欢
    • 1970-01-01
    • 2018-02-07
    • 2023-03-05
    • 2015-08-01
    • 1970-01-01
    • 2019-12-30
    • 2014-10-08
    • 2022-06-11
    • 2015-11-18
    相关资源
    最近更新 更多