【发布时间】:2015-05-27 09:14:38
【问题描述】:
我正在使用 OAuth 为我的应用程序生成令牌,特别是 JWT。我的启动类中有这段代码:
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(DatabaseContext.Create);
app.CreatePerOwinContext<UserService>(UserService.Create);
app.CreatePerOwinContext<RoleService>(RoleService.Create);
// Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new OAuthProvider(),
AccessTokenFormat = new CustomJwtFormat("http://localhost:58127")
};
// OAuth 2.0 Bearer Access Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
如您所见,我设置了自定义 OAuthProvider,而对于 AccessTokenFormat,我使用的是 CustomJwtFormat。 OAuthProvider 如下所示:
public class OAuthProvider : OAuthAuthorizationServerProvider
{
/// <summary>
/// Validate client authentication
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// Validate all requests (because our front end is trusted)
context.Validated();
// Return nothing
return Task.FromResult<object>(null);
}
/// <summary>
/// Validate user credentials
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// Allow any origin
var allowedOrigin = "*";
// Add the access control allow all to our headers
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
// Get our user service
var service = context.OwinContext.GetUserManager<UserService>();
// Find out user
var user = await service.FindAsync(context.UserName, context.Password);
// If the user is not found
if (user == null)
{
// Set an error
context.SetError("invalid_grant", "The user name or password is incorrect.");
// Return from the function
return;
}
// If the user has not confirmed their account
if (!user.EmailConfirmed)
{
// Set an error
context.SetError("invalid_grant", "User did not confirm email.");
// Return from the function
return;
}
// Generate the identity for the user
var oAuthIdentity = await user.GenerateUserIdentityAsync(service, "JWT");
// Create a new ticket
var ticket = new AuthenticationTicket(oAuthIdentity, null);
// Add the ticked to the validated context
context.Validated(ticket);
}
}
这很简单。此外,CustomJwtFormat 类如下所示:
/// <summary>
/// JWT Format
/// </summary>
public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
// Create our private property
private readonly string issuer;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="issuer">The issuer</param>
public CustomJwtFormat(string issuer)
{
this.issuer = issuer;
}
/// <summary>
/// Method to create our JWT token
/// </summary>
/// <param name="data">The Authentication ticket</param>
/// <returns></returns>
public string Protect(AuthenticationTicket data)
{
// If no data is supplied, throw an exception
if (data == null)
throw new ArgumentNullException("data");
// Get our values from our appSettings
string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["as:AudienceSecret"];
// Decode our secret and encrypt the bytes
var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
var signingKey = new HmacSigningCredentials(keyByteArray);
// Get our issue and expire dates in UNIX timestamps
var issued = data.Properties.IssuedUtc;
var expires = data.Properties.ExpiresUtc;
// Create our new token
var token = new JwtSecurityToken(this.issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
// Create a handler
var handler = new JwtSecurityTokenHandler();
// Write our token string
var jwt = handler.WriteToken(token);
// Return our token string
return jwt;
}
/// <summary>
///
/// </summary>
/// <param name="protectedText"></param>
/// <returns></returns>
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
这是关键。它使用 Thinktecture 生成令牌。如下所示的行:
// Create our new token
var token = new JwtSecurityToken(this.issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
// Create a handler
var handler = new JwtSecurityTokenHandler();
// Write our token string
var jwt = handler.WriteToken(token);
这会返回您对令牌的期望(access_token、expires_in 和 token_type),但我也想返回一些用户信息。用户名、角色等。
有人知道我该怎么做吗?
【问题讨论】:
标签: c# asp.net-web-api