예제 #1
0
        public void SetAuthorizationCodeLifetime_AddsLifetime(string lifetime)
        {
            // Arrange
            var ticket = new AuthenticationTicket(
                new ClaimsIdentity(),
                new AuthenticationProperties());

            // Act
            ticket.SetAuthorizationCodeLifetime(lifetime != null ? (TimeSpan?)TimeSpan.ParseExact(lifetime, "c", CultureInfo.InvariantCulture) : null);

            // Assert
            Assert.Equal(lifetime, ticket.GetProperty(OpenIdConnectConstants.Properties.AuthorizationCodeLifetime));
        }
예제 #2
0
        private async Task <AuthenticationTicket> CreateTicketAsync(User user, string[] roles)
        {
            var req = HttpContext.GetOpenIdConnectRequest();

            // principal = authenticated user.
            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            AddRolesToPrincipal(principal, roles);

            var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme);

            // Token lifetime to 12 hours
            ticket.SetAccessTokenLifetime(TimeSpan.FromHours(12));
            ticket.SetAuthorizationCodeLifetime(TimeSpan.FromHours(12));
            ticket.SetIdentityTokenLifetime(TimeSpan.FromHours(12));

            ticket.SetScopes(OpenIddictConstants.Scopes.Roles);

            // Explicitly specify which claims should be included in the access token
            foreach (var claim in ticket.Principal.Claims)
            {
                // Never include the security stamp (it's a secret value)
                if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
                {
                    continue;
                }

                // TODO: If there are any other private/secret claims on the user that should
                // not be exposed publicly, handle them here!
                // The token is encoded but not encrypted, so it is effectively plaintext.

                claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken);
            }

            return(ticket);
        }
예제 #3
0
        public async Task <IActionResult> Token(OpenIdConnectRequest requestModel)
        {
            if (!requestModel.IsPasswordGrantType())
            {
                // Return bad request if the request is not for password grant type
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIdConnectConstants.Errors.UnsupportedGrantType,
                    ErrorDescription = "The specified grant type is not supported."
                }));
            }

            var user = await userManager.FindByNameAsync(requestModel.Username);

            if (user == null)
            {
                // Return bad request if the user doesn't exist
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIdConnectConstants.Errors.InvalidGrant,
                    ErrorDescription = "Invalid username or password"
                }));
            }

            // Check that the user can sign in and is not locked out.
            // If two-factor authentication is supported, it would also be appropriate to check that 2FA is enabled for the user
            if (!await signInManager.CanSignInAsync(user) || (userManager.SupportsUserLockout && await userManager.IsLockedOutAsync(user)))
            {
                // Return bad request is the user can't sign in
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIdConnectConstants.Errors.InvalidGrant,
                    ErrorDescription = "The specified user cannot sign in."
                }));
            }

            if (!await userManager.CheckPasswordAsync(user, requestModel.Password))
            {
                // Return bad request if the password is invalid
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIdConnectConstants.Errors.InvalidGrant,
                    ErrorDescription = "Invalid username or password"
                }));
            }

            // The user is now validated, so reset lockout counts, if necessary
            if (userManager.SupportsUserLockout)
            {
                await userManager.ResetAccessFailedCountAsync(user);
            }

            // Create the principal
            var principal = await signInManager.CreateUserPrincipalAsync(user);

            // Claims will not be associated with specific destinations by default, so we must indicate whether they should
            // be included or not in access and identity tokens.
            foreach (var claim in principal.Claims)
            {
                // For this sample, just include all claims in all token types.
                // In reality, claims' destinations would probably differ by token type and depending on the scopes requested.
                claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);
            }

            // Create a new authentication ticket for the user's principal
            var ticket = new AuthenticationTicket(
                principal,
                new AuthenticationProperties(),
                OpenIdConnectServerDefaults.AuthenticationScheme);

            // Include resources and scopes, as appropriate
            var scope = new[]
            {
                OpenIdConnectConstants.Scopes.OpenId,
                OpenIdConnectConstants.Scopes.Email,
                OpenIdConnectConstants.Scopes.Profile,
                OpenIdConnectConstants.Scopes.OfflineAccess,
                OpenIddictConstants.Scopes.Roles
            }.Intersect(requestModel.GetScopes());

            ticket.SetScopes(scope);
            ticket.SetAccessTokenLifetime(new TimeSpan(3, 0, 0));
            ticket.SetAuthorizationCodeLifetime(new TimeSpan(3, 0, 0));

            // Sign in the user
            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }