public ProtectedResource(Uri baseUri, string[] scopes, AuthenticationFlow authenticationFlow = AuthenticationFlow.OnBehalfOf)
 {
     BaseUri            = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
     Scopes             = scopes ?? throw new ArgumentNullException(nameof(scopes));
     AuthenticationFlow = authenticationFlow;
     AcquireTokenAsync  = CreateTokenCallback(AuthenticationFlow, Scopes);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationFlowTest"/> class.
        /// </summary>
        /// <param name="outputHelper">The test output helper.</param>
        public AuthenticationFlowTest(ITestOutputHelper outputHelper)
        {
            this.outputHelper             = outputHelper;
            this.testDatabase             = new TestDatabase(outputHelper);
            this.dbContext                = this.testDatabase.CreateContext();
            this.identityInstance         = IdentityTestHelper.CreateInstance(this.testDatabase, this.outputHelper);
            this.usedHttpContext          = new DefaultHttpContext();
            this.httpConctextAccessorMock = new Mock <IHttpContextAccessor>();
            this.jwtCrypoMock             = new Mock <IJwtCryptoProvider>();
            this.momentMock               = MomentTestHelper.CreateMomentMock();
            this.optionsMonitorMock       = OptionsTestHelper.CreateBackendOptionsMock();
            this.randomGenerator          = new SecureRandomGenerator();
            this.loggerFactory            = LoggingTestHelper.CreateLoggerFactory(this.outputHelper);

            this.httpConctextAccessorMock.SetupGet(m => m.HttpContext).Returns(this.usedHttpContext);

            this.jwtCrypoMock.SetupGet(c => c.Algorithm).Returns(SigningAlgorithm);
            this.jwtCrypoMock.SetupGet(c => c.SecurityKey).Returns(SigningKey);

            this.authenticationFlow = new AuthenticationFlow(
                this.httpConctextAccessorMock.Object,
                this.jwtCrypoMock.Object,
                this.identityInstance.UserManager,
                this.dbContext,
                this.randomGenerator,
                this.momentMock.Object,
                this.optionsMonitorMock.Object,
                this.loggerFactory.CreateLogger <AuthenticationFlow>());
        }
示例#3
0
        public async Task <bool> CreateAuthenticationFlowAsync(string realm, AuthenticationFlow authenticationFlow)
        {
            var response = await GetBaseUrl(realm)
                           .AppendPathSegment($"/admin/realms/{realm}/authentication/flows")
                           .PostJsonAsync(authenticationFlow)
                           .ConfigureAwait(false);

            return(response.IsSuccessStatusCode);
        }
示例#4
0
 /// <summary>
 /// No validations are performed using this constructor
 /// </summary>
 /// <param name="authority"></param>
 /// <param name="authorizationEndpointRelativePath"></param>
 /// <param name="clientId"></param>
 /// <param name="clientSecret"></param>
 /// <param name="scope"></param>
 /// <param name="username"></param>
 /// <param name="password"></param>
 /// <param name="authenticationFlow"></param>
 public Options(Uri authority, string authorizationEndpointRelativePath, string clientId, string clientSecret, string scope, string username, string password, AuthenticationFlow authenticationFlow)
 {
     Authority          = authority;
     ClientId           = clientId;
     ClientSecret       = clientSecret;
     Scope              = scope;
     Username           = username;
     Password           = password;
     AuthenticationFlow = authenticationFlow;
     AuthorizationEndpointRelativePath = authorizationEndpointRelativePath;
 }
        public ProtectedResource(string baseUrl, string scopes, AuthenticationFlow authenticationFlow = AuthenticationFlow.OnBehalfOf)
        {
            if (string.IsNullOrEmpty(baseUrl))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(baseUrl));
            }

            BaseUri = new Uri(baseUrl);
            Scopes  = !string.IsNullOrEmpty(scopes)
                ? scopes.Split(' ', StringSplitOptions.RemoveEmptyEntries)
                : Array.Empty <string>();
            AuthenticationFlow = authenticationFlow;
            AcquireTokenAsync  = CreateTokenCallback(AuthenticationFlow, Scopes);
        }
        private static Func <ITokenAcquisition, Task <string> > CreateTokenCallback(AuthenticationFlow authenticationFlow, string[] scopes)
        {
            switch (authenticationFlow)
            {
            case AuthenticationFlow.ClientCredentials:
                var scope = scopes.Single();
                return(tokenProvider => tokenProvider.GetAccessTokenForAppAsync(scope));

            case AuthenticationFlow.OnBehalfOf:
                return(tokenProvider => tokenProvider.GetAccessTokenForUserAsync(scopes));

            default:
                throw new Exception($"AuthenticationFlow \"{authenticationFlow}\" not recognized.");
            }
        }
示例#7
0
        private async Task <string> GenerateAccessToken(Entity.User user, AuthenticationFlow authenticationFlow)
        {
            try
            {
                var roles = await userManager.GetRolesAsync(user);

                if (roles is null)
                {
                    return(null);
                }

                var claims = GenerateUserClaims(user, roles, authenticationFlow);

                if (claims is null)
                {
                    return(null);
                }

                var key   = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenSettings.Secret));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                var token = new JwtSecurityToken(
                    issuer: tokenSettings.Issuer,
                    audience: tokenSettings.Issuer,
                    claims,
                    expires: DateTime.Now.AddDays(Convert.ToDouble(tokenSettings.AccessTokenExpirationInDays)),
                    signingCredentials: creds
                    );

                return(new JwtSecurityTokenHandler().WriteToken(token));
            }
            catch (Exception ex)
            {
                logger.LogError($"Generating access token for user: {user.Id} was not successfull", ex);
                throw;
            }
        }
示例#8
0
        private IList <Claim> GenerateUserClaims(Entity.User user, IList <string> roles, AuthenticationFlow authenticationFlow)
        {
            try
            {
                var claims = new List <Claim>
                {
                    new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
                };

                if (authenticationFlow.Equals(AuthenticationFlow.Full))
                {
                    var roleClaims = roles.Select(r => new Claim(ClaimTypes.Role, r));
                    claims.AddRange(roleClaims);
                }

                return(claims);
            }
            catch (Exception ex)
            {
                logger.LogError($"Claims could not be generated for user: {user.Id}", ex);
                throw;
            }
        }
示例#9
0
        public async Task <Result <AuthenticationToken> > GenerateAuthenticationTokenAsync(Entity.User user, string loginProvider, AuthenticationFlow authenticationFlow)
        {
            try
            {
                var accessToken = await GenerateAccessToken(user, authenticationFlow);

                if (accessToken is null)
                {
                    return(new InvalidResult <AuthenticationToken>("Could not generate access token"));
                }

                var refreshToken = GenerateRefreshToken();

                if (refreshToken is null)
                {
                    return(new InvalidResult <AuthenticationToken>("Could not generate access token"));
                }

                var refreshTokenExpiration = DateTime.Now.AddDays(Convert.ToDouble(tokenSettings.RefreshTokenExpirationInDays));
                var accessTokenExpiration  = DateTime.Now.AddDays(Convert.ToDouble(tokenSettings.AccessTokenExpirationInDays));

                var token = await repository.AddUserTokenAsync(new UserToken()
                {
                    UserId                 = user.Id,
                    User                   = user,
                    LoginProvider          = loginProvider,
                    AccessToken            = accessToken,
                    RefreshToken           = refreshToken,
                    RefreshTokenExpiration = refreshTokenExpiration,
                    AccessTokenExpiration  = accessTokenExpiration,
                    AuthenticationFlow     = (int)authenticationFlow,
                });

                if (token is null)
                {
                    return(new InvalidResult <AuthenticationToken>("Could not save new authentication token"));
                }

                var result = mapper.Map <UserToken, AuthenticationToken>(token);

                return(new SuccessResult <AuthenticationToken>(result));
            }
            catch (Exception ex)
            {
                return(new UnexpectedResult <AuthenticationToken>(ex.Message));
            }
        }