Please review my code for bearer token (JWT) authentication of Web API 2 (Self Hosted using OWIN)Are there any security issues in the implementation?Quick overview:Token creation and validation using JWT HandlerSymmetric key encryptionCORS support not yet checked for the authorization headerWeb traffic will be on SSL.The key cannot be auto-generated as it will break during a load balanced scenario. Can I save the key in config? Or switch to X509 certificates?This is the main class to create and validate tokens:public class TokenManager{    public static string CreateJwtToken(string userName, string role)    {        var claimList = new List<Claim>()            {                new Claim(ClaimTypes.Name, userName),                new Claim(ClaimTypes.Role, role)     //Not sure what this is for            };        var tokenHandler = new JwtSecurityTokenHandler() { RequireExpirationTime = true };        var sSKey = new InMemorySymmetricSecurityKey(SecurityConstants.KeyForHmacSha256);        var jwtToken = tokenHandler.CreateToken(            makeSecurityTokenDescriptor(sSKey, claimList));        return tokenHandler.WriteToken(jwtToken);    }    public static ClaimsPrincipal ValidateJwtToken(string jwtToken)    {        var tokenHandler = new JwtSecurityTokenHandler() { RequireExpirationTime = true };        // Parse JWT from the Base64UrlEncoded wire form         //(<Base64UrlEncoded header>.<Base64UrlEncoded body>.<signature>)        JwtSecurityToken parsedJwt = tokenHandler.ReadToken(jwtToken) as JwtSecurityToken;        TokenValidationParameters validationParams =            new TokenValidationParameters()            {                AllowedAudience = SecurityConstants.TokenAudience,                ValidIssuer = SecurityConstants.TokenIssuer,                ValidateIssuer = true,                SigningToken = new BinarySecretSecurityToken(SecurityConstants.KeyForHmacSha256),            };        return tokenHandler.ValidateToken(parsedJwt, validationParams);    }    private static SecurityTokenDescriptor makeSecurityTokenDescriptor(        InMemorySymmetricSecurityKey sSKey, List<Claim> claimList)    {        var now = DateTime.UtcNow;        Claim[] claims = claimList.ToArray();        return new SecurityTokenDescriptor        {            Subject = new ClaimsIdentity(claims),            TokenIssuerName = SecurityConstants.TokenIssuer,            AppliesToAddress = SecurityConstants.TokenAudience,            Lifetime = new Lifetime(now, now.AddMinutes(SecurityConstants.TokenLifetimeMinutes)),            SigningCredentials = new SigningCredentials(sSKey,                http://www.w3.org/2001/04/xmldsig-more#hmac-sha256,                http://www.w3.org/2001/04/xmlenc#sha256),        };    }}I have a message handler to intercept the requests and I verify the validity of token except for the route for log in, using TokenManager.ValidateJwtToken() above.To create the token, in the LoginController, I have the following code:[Route(login)][HttpPost]public HttpResponseMessage Login(LoginBindingModel login){    if (login.Username == admin && login.Password == password)  //Do real auth    {        string role = Librarian;        var jwtToken = TokenManager.CreateJwtToken(login.Username, role);        return new HttpResponseMessage(HttpStatusCode.OK)        {            Content = new ObjectContent<object>(new            {                UserName = login.Username,                Roles = role,                AccessToken = jwtToken            }, Configuration.Formatters.JsonFormatter)        };    }    return new HttpResponseMessage(HttpStatusCode.BadRequest);}The full working code is available here and the instructions to run the sample are in the Wiki.
Web API 2 authentication with JWT
c#;authentication;asp.net web api;jwt