Ejemplo n.º 1
0
        public static IServiceCollection AddAccountsAuthentication(
            this IServiceCollection services,
            AccountsJwtConfiguration configuration)
        {
            services.TryAddScoped <IPasswordHasher <Account>, PasswordHasher <Account> >();

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata      = false;
                x.SaveToken                 = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = configuration.SymmetricSecurityKey,
                    ValidateIssuer           = true,
                    ValidIssuer      = configuration.Issuer,
                    ValidateAudience = true,
                    ValidAudience    = configuration.Audience
                };
            });

            return(services);
        }
        public async ValueTask <TokenRequest> Create(AccountsContext context,
                                                     IPasswordHasher <Account> hasher,
                                                     AccountsJwtConfiguration configuration,
                                                     HttpContext httpContext)
        {
            var account = await context.Accounts
                          .Include(a => a.Tokens)
                          .FirstAsync(a => a.Username == Username);

            var result = hasher.VerifyHashedPassword(account, account.PasswordHash, Password);

            if (result != PasswordVerificationResult.Success)
            {
                throw new UnauthorizedAccessException();
            }

            if (account.Tokens.Count >= configuration.MaxTokensCount)
            {
                context.Tokens.RemoveRange(account.Tokens);
            }

            var secret       = Encoding.ASCII.GetBytes(configuration.Secret);
            var tokenHandler = new JwtSecurityTokenHandler();

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new []
                {
                    new Claim(ClaimTypes.Name, account.Id.ToString()),
                    new Claim(ClaimTypes.Role, account.Role)
                }),
                Expires            = DateTime.UtcNow.AddDays(7),
                Issuer             = configuration.Issuer,
                Audience           = configuration.Audience,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature)
            };

            var access = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));

            var data = new byte[100];

            new Random().NextBytes(data);

            var refresh = Convert.ToBase64String(data);

            var token = new Token
            {
                Account      = account,
                Created      = DateTime.UtcNow,
                IpAddress    = httpContext.Connection.RemoteIpAddress.ToString(),
                UserAgent    = httpContext.Request.Headers[HeaderNames.UserAgent],
                RefreshToken = refresh
            };

            await context.Tokens.AddAsync(token);

            return(new TokenRequest(access, refresh));
        }
        public async ValueTask <TokenRequest> Refresh(AccountsContext context, AccountsJwtConfiguration configuration, HttpContext httpContext)
        {
            var tokenToRemove = await context.Tokens
                                .Include(t => t.Account)
                                .FirstAsync(t => t.RefreshToken == RefreshToken);

            var account = tokenToRemove.Account;

            var tokenHandler = new JwtSecurityTokenHandler();

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new []
                {
                    new Claim(ClaimTypes.Name, account.Id.ToString()),
                    new Claim(ClaimTypes.Role, account.Role)
                }),
                Expires            = DateTime.UtcNow.AddDays(7),
                Issuer             = configuration.Issuer,
                Audience           = configuration.Audience,
                SigningCredentials = new SigningCredentials(
                    configuration.SymmetricSecurityKey,
                    SecurityAlgorithms.HmacSha256Signature)
            };

            var access = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));

            var data = new byte[100];

            new Random().NextBytes(data);

            var refresh = Convert.ToBase64String(data);

            var token = new Token
            {
                Account      = account,
                Created      = DateTime.UtcNow,
                IpAddress    = httpContext.Connection.RemoteIpAddress.ToString(),
                UserAgent    = httpContext.Request.Headers[HeaderNames.UserAgent],
                RefreshToken = refresh
            };

            await context.Tokens.AddAsync(token);

            context.Tokens.Remove(tokenToRemove);

            return(new TokenRequest(access, refresh));
        }
 public TokensController(AccountsContext context, IPasswordHasher <Account> hasher, IOptions <AccountsJwtConfiguration> configuration)
 {
     this.context       = context;
     this.hasher        = hasher;
     this.configuration = configuration.Value;
 }