/// <summary> /// Attempts to authenticate an identity. /// </summary> /// <param name="identifier">The identity's unique identifier.</param> /// <param name="password">The identity's password.</param> /// <param name="serializedToken">The serialized token.</param> /// <returns>Returns whether authentication was successful.</returns> /// <exception cref="EntityNotFoundException">Thrown if no matching identity or any of the role domains could be found.</exception> public async Task <string> Authenticate(string identifier, string password) { // Get identitiy, throws if not found Identity identity = await IdentityService.GetIdentity(identifier); // Reject authentication attempt if identity is disabled if (identity.Disabled) { return(null); } // Reject authentication attempt if bad password provided if (identity.HashedPassword != PasswordHashingService.HashAndSaltPassword(password, identity.Salt)) { return(null); } // Set identity base claims List <Claim> claims = new List <Claim> { // Add subject and unique name new Claim(JwtRegisteredClaimNames.Sub, identity.Id.ToString()), new Claim(JwtRegisteredClaimNames.UniqueName, identity.Identifier), }; // Add identity roles to claims claims.AddRange(await GenerateRoleClaims(identity.Roles)); // Generate and return token return(GenerateNewToken(claims)); }
/// <summary> /// Initializes a new instance of the <see cref="IdentityService"/> class. /// </summary> /// <param name="loggerFactory">A factory to create loggers from.</param> /// <param name="identifierValidationService">Provides validation logic for client-provided identifiers.</param> /// <param name="passwordValidationService">Provides validation logic for client-provided passwords.</param> /// <param name="passwordHashingService">The password hashing service.</param> /// <param name="identityRepository">A repository of identities.</param> public IdentityService(ILoggerFactory loggerFactory, RoleService roleService, IdentifierValidationService identifierValidationService, PasswordValidationService passwordValidationService, PasswordHashingService passwordHashingService, IIdentityRepository identityRepository, IIdentityRoleRepository identityRoleRepository) { Logger = loggerFactory.CreateLogger <IdentityService>(); IdentifierValidationService = identifierValidationService; PasswordValidationService = passwordValidationService; PasswordHashingService = passwordHashingService; IdentityRepository = identityRepository; IdentityRoleRepository = identityRoleRepository; RoleService = roleService; }
/// <summary> /// Creates a new identity. /// </summary> /// <param name="identifier">The unique user-chosen identifier with this identity.</param> /// <param name="password">The as-of-yet unhashed password of this identity.</param> /// <returns></returns> /// <exception cref="EntityAlreadyExsistsException">Identity</exception> public async Task <Identity> CreateIdentity(string identifier, string password) { // Validate identifier format and availability IdentifierValidationService.Validate(identifier); if ((await IdentityRepository.GetIdentity(identifier)) != null) { throw new EntityAlreadyExsistsException("Identity", identifier); } // Validate client-provided password PasswordValidationService.Validate(password); // Hash password and create new identity (string hash, byte[] salt) = PasswordHashingService.HashAndSaltPassword(password); return(await IdentityRepository.CreateIdentity(identifier, hash, salt)); }
/// <summary> /// Sets up the service with all needed dependencies. /// </summary> /// <param name="loggerFactory">Factory to create loggers from.</param> /// <param name="passwordHashingService">Provides password hashing functionalities.</param> /// <param name="identityService">Provides identities.</param> /// <param name="domainService">Provides domain names.</param> /// <param name="configuration">App configuration for JWT signing information.</param> public AuthenticationService(ILoggerFactory loggerFactory, PasswordHashingService passwordHashingService, IdentityService identityService, DomainService domainService, ApiKeyService apiKeyService, IConfiguration configuration) { Logger = loggerFactory.CreateLogger <AuthenticationService>(); PasswordHashingService = passwordHashingService; IdentityService = identityService; DomainService = domainService; ApiKeyService = apiKeyService; // JWT-related configuration SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration.GetValue <string>(ConfigurationPaths.JWT_SECRET))); SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); JwtLifetime = TimeSpan.FromMinutes(configuration.GetValue <int>(ConfigurationPaths.JWT_LIFETIME_IN_MINUTES)); JwtIssuer = configuration.GetValue <string>(ConfigurationPaths.JWT_ISSUER); }