示例#1
0
        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));
        }
示例#2
0
        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);
        }
示例#3
0
 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)
     });
 }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }