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

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

            // Assert
            Assert.Equal(lifetime, ticket.GetProperty(OpenIdConnectConstants.Properties.IdentityTokenLifetime));
        }
예제 #2
0
        public async Task <IActionResult> Authorize(OpenIdConnectRequest request)
        {
            if (request == null)
            {
                throw new System.ArgumentNullException(nameof(request));
            }

            Debug.Assert(request.IsAuthorizationRequest(),
                         "The OpenIddict binder for ASP.NET Core MVC is not registered. " +
                         "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called.");

            // Check if a user is authenticated. If not, challenge the GitHub authentication handler
            if (!User.Identity.IsAuthenticated)
            {
                return(Challenge("Google"));
            }

            var response = await _bus.RequestAsync <GetOrCreateUserRequest, GetOrCreateUserResponse>(new GetOrCreateUserRequest(User.FindFirstValue(ClaimTypes.Email)));

            var userId = response.Id;

            // Create a new ClaimsPrincipal containing the claims that
            // will be used to create an id_token, a token or a code.
            var identity = new ClaimsIdentity("OpenIddict");

            identity.AddClaim(OpenIdConnectConstants.Claims.Subject, userId.ToString(),
                              OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);
            identity.AddClaim(OpenIdConnectConstants.Claims.Name, User.FindFirstValue(ClaimTypes.Name),
                              OpenIdConnectConstants.Destinations.IdentityToken);
            identity.AddClaim(OpenIdConnectConstants.Claims.Email, User.FindFirstValue(ClaimTypes.Email),
                              OpenIdConnectConstants.Destinations.IdentityToken);
            identity.AddClaim(OpenIdConnectConstants.Claims.EmailVerified, "true",
                              OpenIdConnectConstants.Destinations.IdentityToken); // We'll assume email is verified since we get it from GitHub
            var principal = new ClaimsPrincipal(identity);

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

            ticket.SetIdentityTokenLifetime(TimeSpan.FromDays(1));

            // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
예제 #3
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);
        }
        private async Task <AuthenticationTicket> CreateTicketAsync(
            OpenIdConnectRequest request, ApplicationUser user,
            AuthenticationProperties properties = null)
        {
            // Create a new ClaimsPrincipal containing the claims that
            // will be used to create an id_token, a token or a code.
            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            // Create a new authentication ticket holding the user identity.
            var ticket = new AuthenticationTicket(principal,
                                                  properties ?? new AuthenticationProperties(),
                                                  OpenIdConnectServerDefaults.AuthenticationScheme);
            // Set the list of scopes granted to the client application.
            // Note: the offline_access scope must be granted
            // to allow OpenIddict to return a refresh token.

            var roleNames = await _userManager.GetRolesAsync(user);

            var identity = ticket.Principal.Identity as ClaimsIdentity;

            if (!request.IsAuthorizationCodeGrantType())
            {
                var scopes = new List <string>
                {
                    OpenIdConnectConstants.Scopes.OpenId,
                    OpenIdConnectConstants.Scopes.Email,
                    OpenIdConnectConstants.Scopes.Profile,
                    OpenIdConnectConstants.Scopes.OfflineAccess,
                    OpenIddictConstants.Scopes.Roles
                }.Intersect(request.GetScopes()).ToList();
                ticket.SetScopes(scopes);
            }

            // Note: by default, claims are NOT automatically included in the access and identity tokens.
            // To allow OpenIddict to serialize them, you must attach them a destination, that specifies
            // whether they should be included in access tokens, in identity tokens or in both.
            foreach (var claim in ticket.Principal.Claims)
            {
                // Never include the security stamp in the access and identity tokens, as it's a secret value.
                if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
                {
                    continue;
                }

                // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
                // The other claims will only be added to the access_token, which is encrypted when using the default format.
                if ((claim.Type == OpenIdConnectConstants.Claims.Name && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) ||
                    (claim.Type == OpenIdConnectConstants.Claims.Email && ticket.HasScope(OpenIdConnectConstants.Scopes.Email)) ||
                    (claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles)))
                {
                    var type = claim.Type;
                    claim.SetDestinations(OpenIdConnectConstants.Destinations.IdentityToken,
                                          OpenIdConnectConstants.Destinations.AccessToken);
                }
                else
                {
                    claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken);
                }
            }


            if (_appOptions.TokenGeneration.Audiences.Any())
            {
                foreach (var audience in _appOptions.TokenGeneration.Audiences)
                {
                    ticket.SetAudiences(audience);
                }
            }

            if (_appOptions.TokenGeneration.Resources.Any())
            {
                foreach (var resource in _appOptions.TokenGeneration.Resources)
                {
                    ticket.SetResources(resource);
                }
            }

            if (_appOptions.TokenGeneration.IncludeUserIdClaim)
            {
                AddUserIdClaim(ticket, user);
            }

            ticket.SetAccessTokenLifetime(TimeSpan.FromSeconds(_appOptions.TokenGeneration.AccessTokenLifetime));
            ticket.SetIdentityTokenLifetime(TimeSpan.FromSeconds(_appOptions.TokenGeneration.IdentityTokenLifetime));
            ticket.SetRefreshTokenLifetime(TimeSpan.FromSeconds(_appOptions.TokenGeneration.RefreshTokenLifetime));

            return(ticket);
        }