简体   繁体   English

在c#中手动解码OAuth承载令牌

[英]Manually decode OAuth bearer token in c#

In my Web Api 2.2 OWIN based application I have a situation where I manually need to decode the bearer token but I don't know how to do this. 在我的Web Api 2.2基于OWIN的应用程序中,我有一种情况,我手动需要解码承载令牌,但我不知道如何做到这一点。 This is my startup.cs 这是我的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());
    }
}

In my controller Im sending the bearer token as a parameter 在我的控制器中,我发送了承载令牌作为参数

[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
    }
}

How to manually decode and get the claims from the token passed as a parameter? 如何手动解码并从作为参数传递的令牌中获取声明?

NOTE : I know I can send the token in the header and use [Authorize] and (ClaimsIdentity)User.Identity etc but the question is how to read the token when it's not presented in the header. 注意 :我知道我可以在标题中发送令牌并使用[Authorize]和(ClaimsIdentity)User.Identity等,但问题是如何在标题中没有出现时读取令牌。

Just placing this here for others that may visit in the future. 只是将此放在此处可供将来访问的其他人使用。 Solution found at https://long2know.com/2015/05/decrypting-owin-authentication-ticket/ is simpler. https://long2know.com/2015/05/decrypting-owin-authentication-ticket/上找到的解决方案更简单。

Just 2 lines : 只需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);
    } }

I created a sample project for deserializing bearer tokens, which are encrypted using the MachineKeyDataProtector. 我创建了一个用于反序列化承载令牌的示例项目,它使用MachineKeyDataProtector进行加密。 You can take a look at the source code. 您可以查看源代码。

Bearer-Token-Deserializer 承载令牌-解串器

You can read JWT and create Principals and Identity object using the System.IdentityModel.Tokens.Jwt package - https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/ . 您可以使用System.IdentityModel.Tokens.Jwt包读取JWT并创建Principals和Identity对象 - https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/

Here's a quick example that shows the options available when reading and validating the token, 这是一个快速示例,显示了读取和验证令牌时可用的选项,

    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();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM