Skip to content

Instantly share code, notes, and snippets.

@gongdo
Last active March 1, 2016 02:56
Show Gist options
  • Save gongdo/7e6e6c159db7582b1614 to your computer and use it in GitHub Desktop.
Save gongdo/7e6e6c159db7582b1614 to your computer and use it in GitHub Desktop.
JwtBearerAuthentication in ASP.NET5 RC1
//---------------------------------------------------------
// ...in the Startup.cs...
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication();
services.AddAuthorization(options =>
{
var bearerPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
options.AddPolicy(
"Bearer",
bearerPolicy);
});
// prepare the SigningKey for the JwtBearerAuthenticationService.
/* it didn't work on the MONO
var rsa = Convert.FromBase64String("{your RSA TokenSigningKey encoded by Base64}");
RSACryptoServiceProvider publicAndPrivate = new RSACryptoServiceProvider();
publicAndPrivate.ImportCspBlob(rsa);
var parameters = publicAndPrivate.ExportParameters(true);
*/
// It works both .NETCore and MONO environment.
// You need to provide all RSAParameters as byte array.
// To generate a random RSAParameters, see this SO
// http://stackoverflow.com/questions/4233663/generate-random-rsa-keys-with-rsacryptoserviceprovider
var parameters = new RSAParameters
{
D = GetByteArrayFor("d"),
DP = GetByteArrayFor("dp"),
DQ = GetByteArrayFor("dq"),
Exponent = GetByteArrayFor("exponent"),
InverseQ = GetByteArrayFor("inverseQ"),
Modulus = GetByteArrayFor("modulus"),
P = GetByteArrayFor("p"),
Q = GetByteArrayFor("q"),
};
var securityKey = new RsaSecurityKey(parameters);
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256Signature);
// register SigningCredential and the service as singleton to keep this example simple.
services.AddInstance(signingCredentials);
services.AddSingleton<JwtBearerAuthenticationService>();
// Configure JwtBearerOptions
services.Configure<JwtBearerOptions>(options =>
{
options.Audience = "{TokenAudience}";
options.ClaimsIssuer = "{TokenIssuer}";
options.TokenValidationParameters.IssuerSigningKey = securityKey;
options.TokenValidationParameters.ValidAudience = "{TokenAudience}";
options.TokenValidationParameters.ValidIssuer = "{TokenIssuer}";
//... additional options, if necessary...
});
// ...
}
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IOptions<JwtBearerOptions> jwtBearerOptions) // <-- retrieves JwtBearerOptions via Configure() Injection
{
//...
app.UseJwtBearerAuthentication(jwtBearerOptions.Value);
//...
}
//---------------------------------------------------------
// ...in the Controllers...
//...
[Authorize("Bearer")]
[Route("v1/[controller]")]
public class MyController : Controller
{
[AllowAnonymous]
public async Task<IEnumerable<Foo>> Get()
{
//...
}
[Authorize("Bearer", Roles = "TheOne")]
public async Task<Foo> Create()
{
//...
}
}
public class JwtBearerAuthenticationService
{
private readonly JwtBearerOptions options;
private readonly SigningCredentials signingCredentials;
public JwtBearerAuthenticationService(IOptions<JwtBearerOptions> options, SigningCredentials signingCredentials)
{
//...store JwtBearerOptions and SigningCredentials
this.options = options.Value;
this.signingCredentials = signingCredentials;
//...
}
private JwtSecurityTokenHandler GetHandler()
{
var handler = options.SecurityTokenValidators?.OfType<JwtSecurityTokenHandler>().FirstOrDefault();
if (handler == null)
{
throw new InvalidOperationException("JwtSecurityTokenHandler not found.");
}
return handler;
}
// GetToken from the identity you might have.
// or, you can pass simple plain calims.
public virtual string GetToken(ClaimsIdentity identity, DateTime? expires = null)
{
var handler = GetHandler();
var securityToken = handler.CreateJwtSecurityToken(new SecurityTokenDescriptor
{
// ...configure descriptor...
Audience = options.TokenValidationParameters.ValidAudience,
Claims = GetIssuingClaims(identity),
Expires = expires,
Issuer = options.TokenValidationParameters.ValidIssuer,
SigningCredentials = this.signingCredentials
});
return handler.WriteToken(securityToken);
}
private IEnumerable<Claim> GetIssuingClaims(ClaimsIdentity identity)
{
// claim types you want to copy from the given identity
var claimTypesToKeep = new[]
{
System.Security.Claims.ClaimTypes.Name,
System.Security.Claims.ClaimTypes.NameIdentifier,
System.Security.Claims.ClaimTypes.Role,
};
return identity.Claims
.Where(claim => claimTypesToKeep.Contains(claim.Type));
}
public virtual ClaimsPrincipal ValidateAccessToken(string accessToken)
{
var handler = GetHandler();
SecurityToken securityToken;
var principal = handler.ValidateToken(accessToken, options.TokenValidationParameters, out securityToken);
// further validation for securityToken...
//...
return principal;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment