/// <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));
        }
示例#2
0
 /// <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;
 }
示例#3
0
        /// <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);
        }