Skip to content

Instantly share code, notes, and snippets.

@AndriiTsok
Created November 3, 2015 12:17
Show Gist options
  • Save AndriiTsok/23f39e2c41066d4bb856 to your computer and use it in GitHub Desktop.
Save AndriiTsok/23f39e2c41066d4bb856 to your computer and use it in GitHub Desktop.
JWT generate and verify
// don't use this code as-is in production scince ValidateSignature is false
app.Use(async (context, next) =>
{
var authType = IdentityOptions.ApplicationCookieAuthenticationType;
var authScheme = IdentityOptions.ApplicationCookieAuthenticationScheme;
if (context.Request.Path.ToString().ToLower() == "/token")
{
// Generate Token
if (!context.Request.HasFormContentType || !context.Request.Form.ContainsKey("username") || !context.Request.Form.ContainsKey("password"))
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
return;
}
var userName = context.Request.Form["username"];
var password = context.Request.Form["password"];
var userManager = context.ApplicationServices.GetRequiredService<UserManager<ApplicationUser>>();
var user = await userManager.Users.FirstAsync(u => u.UserName == userName);
if (!await userManager.CheckPasswordAsync(user, password))
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
return;
}
var roles = await userManager.GetRolesAsync(user);
var claims = new List<Claim>(new Claim[] { new Claim(ClaimTypes.Name, user.UserName) });
foreach (var r in roles) claims.Add(new Claim(ClaimTypes.Role, r));
foreach (var c in user.Claims) claims.Add(new Claim(c.ClaimType, c.ClaimValue));
var identity = new ClaimsIdentity(claims, authScheme);
var handler = new JwtSecurityTokenHandler();
var rsa = new RSACryptoServiceProvider(2048);
var rsaParams = rsa.ExportParameters(true);
var rsaKey = new RsaSecurityKey(rsaParams);
var secToken = handler.CreateToken("myself", "myself", identity, DateTime.UtcNow, DateTime.UtcNow.AddDays(1),
new SigningCredentials(rsaKey, JwtAlgorithms.RSA_SHA256, JwtAlgorithms.RSA_SHA256, "yourkeyid"));
var token = handler.WriteToken(secToken);
List<string> tokens = null;
if (app.Properties.ContainsKey("tokens"))
tokens = (List<string>)app.Properties["tokens"];
else
{
tokens = new List<string>();
app.Properties.Add("tokens", tokens);
}
tokens.Add(token);
await context.Response.WriteAsync(string.Format("{{\"token_type\":\"{0}\",\"access_token\":\"{1}\"}}", "bearer", token));
return;
}
else if (!context.User.Identities.Any(identity => identity.IsAuthenticated) &&
context.Request.Path.StartsWithSegments(new PathString("/api")))
{
// Validate Token
var token = context.Request.Headers["Authorization"];
var tokens = app.Properties.ContainsKey("tokens") ? (List<string>)app.Properties["tokens"] : null;
if (string.IsNullOrEmpty(token) || token.Substring(0, "bearer ".Length).ToLower() != "bearer " || tokens == null || tokens.Count == 0)
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
return;
}
token = token.Substring("bearer ".Length);
if (!tokens.Contains(token))
{
await next(context);
return;
}
var handler = new JwtSecurityTokenHandler();
var rsa = new RSACryptoServiceProvider(2048);
var rsaParams = rsa.ExportParameters(true);
var rsaKey = new RsaSecurityKey(rsaParams);
var validationParameters = new TokenValidationParameters
{
ValidAudience = "myself",
ValidIssuer = "myself",
RequireExpirationTime = true,
IssuerSigningKey = rsaKey,
AuthenticationType = authType,
RequireSignedTokens = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidateActor = false,
ValidateIssuerSigningKey = true,
ValidateSignature = false, // this feature should be fixed
ValidateLifetime = true,
};
try
{
SecurityToken secToken;
var principal = handler.ValidateToken(token, validationParameters, out secToken);
principal.Identities.First().AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authType));
context.User = principal;
}
catch
{
tokens.Remove(token);
context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
return;
}
}
else if (context.Request.Path == "/signout")
{
// Remove Token
var token = context.Request.Headers["Authorization"];
var tokens = app.Properties.ContainsKey("tokens") ? (List<string>)app.Properties["tokens"] : null;
if (string.IsNullOrEmpty(token) || token.Substring(0, "bearer ".Length).ToLower() != "bearer " || tokens == null || tokens.Count == 0)
return;
token = token.Substring("bearer ".Length);
tokens.Remove(token);
return;
}
await next();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment