在 C# 中手动解码 OAuth 不记名令牌
Manually decode OAuth bearer token in c#
在我的 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
}
}
如何手动解码并从作为参数传递的令牌中获取声明?
注意:我知道我可以在 header 中发送令牌并使用 [Authorize] 和 (ClaimsIdentity)User.Identity 等,但问题是header 中未显示令牌时如何读取令牌。
您可以阅读 JWT 并使用 System.IdentityModel.Tokens.Jwt 包创建主体和身份对象 - 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();
}
我创建了一个用于反序列化使用 MachineKeyDataProtector 加密的不记名令牌的示例项目。
可以看看源码
只是把它放在这里,以供将来可能访问的其他人使用。在 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);
} }
在我的 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
}
}
如何手动解码并从作为参数传递的令牌中获取声明?
注意:我知道我可以在 header 中发送令牌并使用 [Authorize] 和 (ClaimsIdentity)User.Identity 等,但问题是header 中未显示令牌时如何读取令牌。
您可以阅读 JWT 并使用 System.IdentityModel.Tokens.Jwt 包创建主体和身份对象 - 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();
}
我创建了一个用于反序列化使用 MachineKeyDataProtector 加密的不记名令牌的示例项目。 可以看看源码
只是把它放在这里,以供将来可能访问的其他人使用。在 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);
} }