public async Task <IActionResult> Authorize(OpenIdConnectRequest request,
                                                    string consent, bool createAuthorization = true)
        {
            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                return(View("Error",
                            new ErrorViewModel
                {
                    Error = OpenIddictConstants.Errors.ServerError,
                    ErrorDescription = "The specified user could not be found"
                }));
            }

            string type = null;

            switch (consent.ToUpperInvariant())
            {
            case "YESTEMPORARY":
                type = OpenIddictConstants.AuthorizationTypes.AdHoc;
                break;

            case "YES":
                type = OpenIddictConstants.AuthorizationTypes.Permanent;
                break;

            case "NO":
            default:
                // Notify OpenIddict that the authorization grant has been denied by the resource owner
                // to redirect the user agent to the client application using the appropriate response_mode.
                return(Forbid(OpenIddictServerDefaults.AuthenticationScheme));
            }


            // Create a new authentication ticket.
            var ticket =
                await OpenIdExtensions.CreateAuthenticationTicket(_applicationManager, _authorizationManager,
                                                                  _IdentityOptions.Value, _signInManager,
                                                                  request, user);

            if (createAuthorization)
            {
                var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

                var authorization = await _authorizationManager.CreateAsync(User, user.Id, application.Id,
                                                                            type, ticket.GetScopes().ToImmutableArray(),
                                                                            ticket.Properties.Items.ToImmutableDictionary());

                ticket.SetInternalAuthorizationId(authorization.Id);
            }

            // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
Esempio n. 2
0
        public async Task <IActionResult> Authorize(string consent, bool createAuthorization = true)
        {
            var request = HttpContext.GetOpenIddictServerRequest();
            var user    = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                return(View("Error",
                            new ErrorViewModel
                {
                    Error = OpenIddictConstants.Errors.ServerError,
                    ErrorDescription = "The specified user could not be found"
                }));
            }

            string type = null;

            switch (consent.ToUpperInvariant())
            {
            case "YESTEMPORARY":
                type = OpenIddictConstants.AuthorizationTypes.AdHoc;
                break;

            case "YES":
                type = OpenIddictConstants.AuthorizationTypes.Permanent;
                break;

            case "NO":
            default:
                // Notify OpenIddict that the authorization grant has been denied by the resource owner
                // to redirect the user agent to the client application using the appropriate response_mode.
                return(Forbid(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
            }


            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            principal = await _signInManager.CreateUserPrincipalAsync(user);

            principal.SetScopes(request.GetScopes().Restrict(principal));
            principal.SetDestinations(_IdentityOptions.Value);
            if (createAuthorization)
            {
                var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

                var authorization = await _authorizationManager.CreateAsync(User, user.Id, application.Id,
                                                                            type, principal.GetScopes());

                principal.SetInternalAuthorizationId(authorization.Id);
            }

            // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens.
            return(SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
        }
        public async Task <IActionResult> Authorize()
        {
            var request = HttpContext.GetOpenIddictServerRequest() ??
                          throw new InvalidOperationException("The OpenID Connect request cannot be retrieved.");

            // Retrieve the user principal stored in the authentication cookie.
            // If it can't be extracted, redirect the user to the login page.
            var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);

            if (result == null || !result.Succeeded)
            {
                // If the client application requested promptless authentication,
                // return an error indicating that the user is not logged in.
                if (request.HasPrompt(Prompts.None))
                {
                    return(Forbid(
                               authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
                               properties: new AuthenticationProperties(new Dictionary <string, string>
                    {
                        [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired,
                        [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in."
                    })));
                }

                return(Challenge(
                           authenticationSchemes: IdentityConstants.ApplicationScheme,
                           properties: new AuthenticationProperties
                {
                    RedirectUri = Request.PathBase + Request.Path + QueryString.Create(
                        Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
                }));
            }

            // If prompt=login was specified by the client application,
            // immediately return the user agent to the login page.
            if (request.HasPrompt(Prompts.Login))
            {
                // To avoid endless login -> authorization redirects, the prompt=login flag
                // is removed from the authorization request payload before redirecting the user.
                var prompt = string.Join(" ", request.GetPrompts().Remove(Prompts.Login));

                var parameters = Request.HasFormContentType ?
                                 Request.Form.Where(parameter => parameter.Key != Parameters.Prompt).ToList() :
                                 Request.Query.Where(parameter => parameter.Key != Parameters.Prompt).ToList();

                parameters.Add(KeyValuePair.Create(Parameters.Prompt, new StringValues(prompt)));

                return(Challenge(
                           authenticationSchemes: IdentityConstants.ApplicationScheme,
                           properties: new AuthenticationProperties
                {
                    RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters)
                }));
            }

            // If a max_age parameter was provided, ensure that the cookie is not too old.
            // If it's too old, automatically redirect the user agent to the login page.
            if (request.MaxAge != null && result.Properties?.IssuedUtc != null &&
                DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))
            {
                if (request.HasPrompt(Prompts.None))
                {
                    return(Forbid(
                               authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
                               properties: new AuthenticationProperties(new Dictionary <string, string>
                    {
                        [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired,
                        [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in."
                    })));
                }

                return(Challenge(
                           authenticationSchemes: IdentityConstants.ApplicationScheme,
                           properties: new AuthenticationProperties
                {
                    RedirectUri = Request.PathBase + Request.Path + QueryString.Create(
                        Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
                }));
            }

            // Retrieve the profile of the logged in user.
            var user = await _userManager.GetUserAsync(result.Principal) ??
                       throw new InvalidOperationException("The user details cannot be retrieved.");

            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ??
                              throw new InvalidOperationException("Details concerning the calling client application cannot be found.");

            // Retrieve the permanent authorizations associated with the user and the calling client application.
            var authorizations = await _authorizationManager.FindAsync(
                subject : await _userManager.GetUserIdAsync(user),
                client : await _applicationManager.GetIdAsync(application),
                status : Statuses.Valid,
                type : AuthorizationTypes.Permanent,
                scopes : request.GetScopes()).ToListAsync();

            switch (await _applicationManager.GetConsentTypeAsync(application))
            {
            // If the consent is external (e.g when authorizations are granted by a sysadmin),
            // immediately return an error if no authorization can be found in the database.
            case ConsentTypes.External when !authorizations.Any():
                return(Forbid(
                           authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
                           properties: new AuthenticationProperties(new Dictionary <string, string>
                {
                    [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired,
                    [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
                        "The logged in user is not allowed to access this client application."
                })));

            // If the consent is implicit or if an authorization was found,
            // return an authorization response without displaying the consent form.
            case ConsentTypes.Implicit:
            case ConsentTypes.External when authorizations.Any():
            case ConsentTypes.Explicit when authorizations.Any() && !request.HasPrompt(Prompts.Consent):
                var principal = await _signInManager.CreateUserPrincipalAsync(user);

                // Note: in this sample, the granted scopes match the requested scope
                // but you may want to allow the user to uncheck specific scopes.
                // For that, simply restrict the list of scopes before calling SetScopes.
                principal.SetScopes(request.GetScopes());
                principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync());

                // Automatically create a permanent authorization to avoid requiring explicit consent
                // for future authorization or token requests containing the same scopes.
                var authorization = authorizations.LastOrDefault();
                if (authorization == null)
                {
                    authorization = await _authorizationManager.CreateAsync(
                        principal : principal,
                        subject : await _userManager.GetUserIdAsync(user),
                        client : await _applicationManager.GetIdAsync(application),
                        type : AuthorizationTypes.Permanent,
                        scopes : principal.GetScopes());
                }

                principal.SetInternalAuthorizationId(await _authorizationManager.GetIdAsync(authorization));

                foreach (var claim in principal.Claims)
                {
                    claim.SetDestinations(GetDestinations(claim, principal));
                }

                return(SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));

            // At this point, no authorization was found in the database and an error must be returned
            // if the client application specified prompt=none in the authorization request.
            case ConsentTypes.Explicit   when request.HasPrompt(Prompts.None):
            case ConsentTypes.Systematic when request.HasPrompt(Prompts.None):
                return(Forbid(
                           authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
                           properties: new AuthenticationProperties(new Dictionary <string, string>
                {
                    [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired,
                    [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] =
                        "Interactive user consent is required."
                })));

            // In every other case, render the consent form.
            default:
                return(View(new AuthorizeViewModel
                {
                    ApplicationName = await _applicationManager.GetDisplayNameAsync(application),
                    Scope = request.Scope
                }));
            }
        }