Ejemplo n.º 1
0
        private async Task <IActionResult> IssueTokensAsync(
            ClaimsPrincipal principal, OpenIdConnectRequest request,
            IOpenIdApplication application, IOpenIdAuthorization authorization = null)
        {
            // Retrieve the profile of the logged in user.
            var user = await _userManager.GetUserAsync(principal);

            if (user == null)
            {
                return(View("Error", new ErrorViewModel
                {
                    Error = OpenIdConnectConstants.Errors.ServerError,
                    ErrorDescription = T["An internal error has occurred"]
                }));
            }

            var ticket = await CreateTicketAsync(user, application, authorization, request);

            // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
Ejemplo n.º 2
0
        public async Task <IActionResult> Edit(EditOpenIdApplicationViewModel model, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageOpenIdApplications))
            {
                return(Unauthorized());
            }

            if (model.Type == ClientType.Public && !string.IsNullOrEmpty(model.ClientSecret))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), T["No client secret can be set for public applications."]);
            }
            else if (model.UpdateClientSecret)
            {
                var user = await _userManager.FindByNameAsync(User.Identity.Name);
                await ValidateClientSecretAsync(user, model.ClientSecret, (key, message) => ModelState.AddModelError(key, message));
            }

            if (!model.AllowAuthorizationCodeFlow && !model.AllowClientCredentialsFlow &&
                !model.AllowImplicitFlow && !model.AllowPasswordFlow && !model.AllowRefreshTokenFlow)
            {
                ModelState.AddModelError(string.Empty, "At least one flow must be enabled.");
            }

            IOpenIdApplication application = null;

            if (ModelState.IsValid)
            {
                application = await _applicationManager.FindByPhysicalIdAsync(model.Id);

                if (application == null)
                {
                    return(NotFound());
                }

                if (model.Type == ClientType.Confidential && !model.UpdateClientSecret &&
                    await _applicationManager.IsPublicAsync(application))
                {
                    ModelState.AddModelError(nameof(model.UpdateClientSecret), T["Setting a new client secret is required"]);
                }

                var other = await _applicationManager.FindByClientIdAsync(model.ClientId);

                if (other != null && !string.Equals(
                        await _applicationManager.GetIdAsync(other),
                        await _applicationManager.GetIdAsync(application), StringComparison.Ordinal))
                {
                    ModelState.AddModelError(nameof(model.ClientId), T["The client identifier is already taken by another application."]);
                }
            }

            if (!ModelState.IsValid)
            {
                var openIdSettings = await _openIdService.GetOpenIdSettingsAsync();

                if (!_openIdService.IsValidOpenIdSettings(openIdSettings))
                {
                    _notifier.Warning(H["OpenID Connect settings are not properly configured."]);
                }

                ViewData["OpenIdSettings"] = openIdSettings;
                ViewData["ReturnUrl"]      = returnUrl;
                return(View(model));
            }

            await _applicationManager.UpdateAsync(application, model);

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(RedirectToAction("Index"));
            }

            return(LocalRedirect(returnUrl));
        }
 Task IOpenIdApplicationStore.SetRolesAsync(IOpenIdApplication application, ImmutableArray <string> roles, CancellationToken cancellationToken)
 => SetRolesAsync((OpenIdApplication)application, roles, cancellationToken);
 Task <ImmutableArray <string> > IOpenIdApplicationStore.GetRolesAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => GetRolesAsync((OpenIdApplication)application, cancellationToken);
 Task <string> IOpenIdApplicationStore.GetPhysicalIdAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => GetPhysicalIdAsync((OpenIdApplication)application, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .UpdateAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => UpdateAsync((OpenIdApplication)application, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetRedirectUrisAsync(IOpenIdApplication application,
                                                                             ImmutableArray <string> addresses, CancellationToken cancellationToken)
 => SetRedirectUrisAsync((OpenIdApplication)application, addresses, cancellationToken);
 Task <JObject> IOpenIddictApplicationStore <IOpenIdApplication> .GetPropertiesAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => GetPropertiesAsync((OpenIdApplication)application, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetPermissionsAsync(IOpenIdApplication application, ImmutableArray <string> permissions, CancellationToken cancellationToken)
 => SetPermissionsAsync((OpenIdApplication)application, permissions, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetDisplayNameAsync(IOpenIdApplication application, string name, CancellationToken cancellationToken)
 => SetDisplayNameAsync((OpenIdApplication)application, name, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetConsentTypeAsync(IOpenIdApplication application, string type, CancellationToken cancellationToken)
 => SetConsentTypeAsync((OpenIdApplication)application, type, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetClientSecretAsync(IOpenIdApplication application, string secret, CancellationToken cancellationToken)
 => SetClientSecretAsync((OpenIdApplication)application, secret, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetClientIdAsync(IOpenIdApplication application,
                                                                         string identifier, CancellationToken cancellationToken)
 => SetClientIdAsync((OpenIdApplication)application, identifier, cancellationToken);
 Task <ImmutableArray <string> > IOpenIddictApplicationStore <IOpenIdApplication> .GetRedirectUrisAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => GetRedirectUrisAsync((OpenIdApplication)application, cancellationToken);
 Task IOpenIddictApplicationStore <IOpenIdApplication> .SetPropertiesAsync(IOpenIdApplication application, JObject properties, CancellationToken cancellationToken)
 => SetPropertiesAsync((OpenIdApplication)application, properties, cancellationToken);
Ejemplo n.º 16
0
        private async Task <AuthenticationTicket> CreateTicketAsync(
            IUser user, IOpenIdApplication application, IOpenIdAuthorization authorization,
            OpenIdConnectRequest request, AuthenticationProperties properties = null)
        {
            Debug.Assert(request.IsAuthorizationRequest() || request.IsTokenRequest(),
                         "The request should be an authorization or token request.");

            // 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);

            var identity = (ClaimsIdentity)principal.Identity;

            // Note: while ASP.NET Core Identity uses the legacy WS-Federation claims (exposed by the ClaimTypes class),
            // OpenIddict uses the newer JWT claims defined by the OpenID Connect specification. To ensure the mandatory
            // subject claim is correctly populated (and avoid an InvalidOperationException), it's manually added here.
            if (string.IsNullOrEmpty(principal.FindFirstValue(OpenIdConnectConstants.Claims.Subject)))
            {
                identity.AddClaim(new Claim(OpenIdConnectConstants.Claims.Subject, await _userManager.GetUserIdAsync(user)));
            }

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

            if (request.IsAuthorizationRequest() || (!request.IsAuthorizationCodeGrantType() &&
                                                     !request.IsRefreshTokenGrantType()))
            {
                // 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.
                ticket.SetScopes(new[]
                {
                    OpenIdConnectConstants.Scopes.OpenId,
                    OpenIdConnectConstants.Scopes.Email,
                    OpenIdConnectConstants.Scopes.Profile,
                    OpenIdConnectConstants.Scopes.OfflineAccess,
                    OpenIddictConstants.Scopes.Roles
                }.Intersect(request.GetScopes()));

                ticket.SetResources(await GetResourcesAsync(request));

                // If the request is an authorization request, automatically create
                // a permanent authorization to avoid requiring explicit consent for
                // future authorization or token requests containing the same scopes.
                if (authorization == null && request.IsAuthorizationRequest())
                {
                    authorization = await _authorizationManager.CreateAsync(
                        principal : ticket.Principal,
                        subject : await _userManager.GetUserIdAsync(user),
                        client : await _applicationManager.GetIdAsync(application),
                        type : OpenIddictConstants.AuthorizationTypes.Permanent,
                        scopes : ImmutableArray.CreateRange(ticket.GetScopes()),
                        properties : ImmutableDictionary.CreateRange(ticket.Properties.Items));
                }

                if (authorization != null)
                {
                    // Attach the authorization identifier to the authentication ticket.
                    ticket.SetProperty(OpenIddictConstants.Properties.AuthorizationId,
                                       await _authorizationManager.GetIdAsync(authorization));
                }
            }

            // 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;
                }

                var destinations = new List <string>
                {
                    OpenIdConnectConstants.Destinations.AccessToken
                };

                // 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)))
                {
                    destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
                }

                claim.SetDestinations(destinations);
            }

            return(ticket);
        }
 Task <string> IOpenIddictApplicationStore <IOpenIdApplication> .GetIdAsync(IOpenIdApplication application, CancellationToken cancellationToken)
 => GetIdAsync((OpenIdApplication)application, cancellationToken);