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; }