public async Task <string> GenerateTokenAsync( ApplicationUser user, DateTime expires, string refreshToken, string aesKey, string rsaPublicKey, MixAuthenticationConfigurations appConfigs) { List <Claim> claims = await GetClaimsAsync(user, appConfigs); claims.AddRange(new[] { new Claim(MixClaims.Id, user.Id.ToString()), new Claim(MixClaims.Username, user.UserName), new Claim(MixClaims.RefreshToken, refreshToken), new Claim(MixClaims.AESKey, aesKey), new Claim(MixClaims.RSAPublicKey, rsaPublicKey) }); JwtSecurityToken jwtSecurityToken = new JwtSecurityToken( issuer: appConfigs.Issuer, audience: appConfigs.Audience, claims: claims, notBefore: expires.AddMinutes(-appConfigs.AccessTokenExpiration), expires: expires, signingCredentials: new SigningCredentials(JwtSecurityKey.Create(appConfigs.SecretKey), SecurityAlgorithms.HmacSha256)); return(new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken)); }
public async Task <List <Claim> > GetClaimsAsync(ApplicationUser user, MixAuthenticationConfigurations appConfigs) { List <Claim> claims = new List <Claim>(); var userRoles = await _userManager.GetRolesAsync(user); foreach (var claim in user.Claims) { claims.Add(CreateClaim(claim.ClaimType, claim.ClaimValue)); } foreach (var userRole in userRoles) { claims.Add(new Claim(ClaimTypes.Role, userRole)); var role = await _roleManager.FindByNameAsync(userRole); if (role != null) { var roleClaims = await _roleManager.GetClaimsAsync(role); foreach (Claim roleClaim in roleClaims) { claims.Add(roleClaim); } } } return(claims); }
public TokenValidationParameters GetValidationParameters(MixAuthenticationConfigurations appConfigs, bool validateLifetime) { return(new TokenValidationParameters { ClockSkew = TimeSpan.Zero, ValidateIssuer = appConfigs.ValidateIssuer, ValidateAudience = appConfigs.ValidateAudience, ValidateLifetime = validateLifetime, ValidateIssuerSigningKey = appConfigs.ValidateIssuerSigningKey, IssuerSigningKey = JwtSecurityKey.Create(appConfigs.SecretKey) }); }
public ClaimsPrincipal GetPrincipalFromExpiredToken(string token, MixAuthenticationConfigurations appConfigs) { var tokenValidationParameters = GetValidationParameters(appConfigs, false); var tokenHandler = new JwtSecurityTokenHandler(); SecurityToken securityToken; var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out securityToken); var jwtSecurityToken = securityToken as JwtSecurityToken; if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) { return(null); } return(principal); }
public static IServiceCollection AddMixAuthorize <TDbContext>(this IServiceCollection services, MixAuthenticationConfigurations authConfigurations) where TDbContext : DbContext { PasswordOptions pOpt = new PasswordOptions() { RequireDigit = false, RequiredLength = 6, RequireLowercase = false, RequireNonAlphanumeric = false, RequireUppercase = false }; const string accessDeniedPath = "/security/login"; services.AddIdentity <ApplicationUser, IdentityRole>(options => { options.Password = pOpt; options.User = new UserOptions() { RequireUniqueEmail = true }; }) .AddEntityFrameworkStores <TDbContext>() .AddDefaultTokenProviders() .AddUserManager <UserManager <ApplicationUser> >(); services.AddAuthorization(); services.AddAuthentication(authConfigurations.TokenType) .AddFacebookIf( !string.IsNullOrEmpty(authConfigurations.Facebook?.AppId), authConfigurations.Facebook, accessDeniedPath) .AddGoogleIf( !string.IsNullOrEmpty(authConfigurations.Google?.AppId), authConfigurations.Google, accessDeniedPath) .AddTwitterIf( !string.IsNullOrEmpty(authConfigurations.Twitter?.AppId), authConfigurations.Twitter, accessDeniedPath) .AddMicrosoftAccountIf( !string.IsNullOrEmpty(authConfigurations.Microsoft?.AppId), authConfigurations.Microsoft, accessDeniedPath) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ClockSkew = TimeSpan.Zero, ValidateIssuer = authConfigurations.ValidateIssuer, ValidateAudience = authConfigurations.ValidateAudience, ValidateLifetime = true, ValidateIssuerSigningKey = authConfigurations.ValidateIssuerSigningKey, ValidIssuers = authConfigurations.Issuers.Split(','), ValidAudiences = authConfigurations.Audiences.Split(','), IssuerSigningKey = JwtSecurityKey.Create(authConfigurations.SecretKey) }; // TODO Handle Custom Auth //options.Events = new JwtBearerEvents //{ // OnAuthenticationFailed = context => // { // Console.WriteLine("OnAuthenticationFailed: " + context.Exception.Message); // return Task.CompletedTask; // }, // OnTokenValidated = context => // { // Console.WriteLine("OnTokenValidated: " + context.SecurityToken); // return Task.CompletedTask; // }, //}; }); services.ConfigureApplicationCookie(options => { options.Cookie.HttpOnly = true; options.Cookie.MaxAge = TimeSpan.FromMinutes(authConfigurations.AccessTokenExpiration); options.ExpireTimeSpan = TimeSpan.FromMinutes(authConfigurations.AccessTokenExpiration); options.LoginPath = accessDeniedPath; options.LogoutPath = "/"; options.AccessDeniedPath = accessDeniedPath; options.SlidingExpiration = true; }); services.AddScoped <MixIdentityHelper>(); return(services); }
public async Task <ParsedExternalAccessToken> VerifyExternalAccessToken(MixExternalLoginProviders provider, string accessToken, MixAuthenticationConfigurations appConfigs) { ParsedExternalAccessToken parsedToken = null; string verifyTokenEndPoint; switch (provider) { case MixExternalLoginProviders.Facebook: //You can get it from here: https://developers.facebook.com/tools/accesstoken/ //More about debug_tokn here: http://stackoverflow.com/questions/16641083/how-does-one-get-the-app-access-token-for-debug-token-inspection-on-facebook var appToken = $"{appConfigs.Facebook.AppId}|{appConfigs.Facebook.AppSecret}"; verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken); break; case MixExternalLoginProviders.Google: verifyTokenEndPoint = string.Format("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={0}", accessToken); break; case MixExternalLoginProviders.Twitter: case MixExternalLoginProviders.Microsoft: default: return(null); } var client = new HttpClient(); var uri = new Uri(verifyTokenEndPoint); var response = await client.GetAsync(uri); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); dynamic jObj = JObject.Parse(content); parsedToken = new ParsedExternalAccessToken(); if (provider == MixExternalLoginProviders.Facebook) { parsedToken.user_id = jObj["data"]["user_id"]; parsedToken.app_id = jObj["data"]["app_id"]; if (!string.Equals(appConfigs.Facebook.AppId, parsedToken.app_id, StringComparison.OrdinalIgnoreCase)) { return(null); } } else if (provider == MixExternalLoginProviders.Google) { parsedToken.user_id = jObj["user_id"]; parsedToken.app_id = jObj["audience"]; if (!string.Equals(appConfigs.Google.AppId, parsedToken.app_id, StringComparison.OrdinalIgnoreCase)) { return(null); } } } return(parsedToken); }