예제 #1
0
        public async Task <IActionResult> Authorize()
        {
            var request = HttpContext.GetOpenIddictServerRequest() ??
                          throw new InvalidOperationException("The OpenID Connect request 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.");

            return(View(new AuthorizeViewModel
            {
                ApplicationName = await _applicationManager.GetDisplayNameAsync(application),
                Scope = request.Scope
            }));
        }
예제 #2
0
        public async Task <IActionResult> Exchange()
        {
            var request = HttpContext.GetOpenIddictServerRequest();

            if (request.IsAuthorizationCodeGrantType())
            {
                // Note: the client credentials are automatically validated by OpenIddict:
                // if client_id or client_secret are invalid, this action won't be invoked.

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

                if (application == null)
                {
                    throw new InvalidOperationException("The application details cannot be found in the database.");
                }

                // Create a new ClaimsIdentity containing the claims that
                // will be used to create an id_token, a token or a code.
                var identity = new ClaimsIdentity(
                    TokenValidationParameters.DefaultAuthenticationType,
                    Claims.Name, Claims.Role);

                // Use the client_id as the subject identifier.
                identity.AddClaim(Claims.Subject, await _applicationManager.GetClientIdAsync(application),
                                  Destinations.AccessToken, Destinations.IdentityToken);

                identity.AddClaim(Claims.Name, await _applicationManager.GetDisplayNameAsync(application),
                                  Destinations.AccessToken, Destinations.IdentityToken);

                return(SignIn(new ClaimsPrincipal(identity), OpenIddictServerAspNetCoreDefaults.AuthenticationScheme));
            }

            throw new NotImplementedException("The specified grant type is not implemented.");
        }
예제 #3
0
        public async Task <IActionResult> Authorize(OpenIdConnectRequest request)
        {
            Debug.Assert(request.IsAuthorizationRequest(),
                         "The OpenIddict binder for ASP.NET Core MVC is not registered. " +
                         "Make sure services.AddOpenIddict().AddServer().UseMvc() is correctly called.");

            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(View("Error", new ErrorViewModel
                {
                    Error = OpenIdConnectConstants.Errors.InvalidClient,
                    ErrorDescription = "Details concerning the calling client application cannot be found in the database"
                }));
            }

            // Flow the request_id to allow OpenIddict to restore
            // the original authorization request from the cache.
            return(View(new AuthorizeViewModel
            {
                ApplicationName = await _applicationManager.GetDisplayNameAsync(application),
                RequestId = request.RequestId,
                Scope = request.Scope
            }));
        }
        public async Task <IActionResult> Authorize(OpenIdConnectRequest request)
        {
            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(View("Error",
                            new ErrorViewModel
                {
                    Error = OpenIddictConstants.Errors.InvalidClient,
                    ErrorDescription =
                        "Details concerning the calling client application cannot be found in the database"
                }));
            }

            var userId = _userManager.GetUserId(User);

            if (!string.IsNullOrEmpty(
                    await OpenIdExtensions.IsUserAuthorized(_authorizationManager, request, userId, application.Id)))
            {
                return(await Authorize(request, "YES", false));
            }

            // Flow the request_id to allow OpenIddict to restore
            // the original authorization request from the cache.
            return(View(new AuthorizeViewModel
            {
                ApplicationName = await _applicationManager.GetDisplayNameAsync(application),
                RequestId = request.RequestId,
                Scope = request.GetScopes()
            }));
        }
예제 #5
0
        public async Task <IActionResult> Authorize()
        {
            var request = HttpContext.GetOpenIddictServerRequest();

            if (request == null)
            {
                throw new InvalidOperationException("The OpenID Connect request cannot be retrieved.");
            }

            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(View("Error", new ErrorViewModel
                {
                    Error = Errors.InvalidClient,
                    ErrorDescription = "Details concerning the calling client application cannot be found in the database"
                }));
            }

            // Flow the request_id to allow OpenIddict to restore
            // the original authorization request from the cache.
            return(View(new AuthorizeViewModel
            {
                ApplicationName = await _applicationManager.GetDisplayNameAsync(application),
                Parameters = request.GetFlattenedParameters(),
                Scope = request.Scope
            }));
        }
예제 #6
0
        public async Task <IActionResult> Authorize(OpenIdConnectRequest req)
        {
            //Debug.Assert(request.IsAuthorizationRequest(),
            //    "The OpenIddict binder for ASP.NET Core MVC is not registered." +
            //    "Make sure services.AddOpenIddict().AddServer().UseMvc() is correctly called.");

            var application = await applicationManager.FindByClientIdAsync(req.ClientId);

            if (application == null)
            {
                var msg = "Details concerning the calling client application cannot be found in the database";
                return(BadRequest(error: new ErrowVm
                {
                    Error = Errors.InvalidClient,
                    ErrorDescription = msg
                }.ToResponse(false, msg)));
            }

            return(Ok(new AuthorizeVm
            {
                ApplicationName = await applicationManager.GetDisplayNameAsync(application),
                RequestId = req.RequestId,
                Scope = req.Scope
            }.ToResponse()));
        }
예제 #7
0
        private async Task <IActionResult> ExchangeClientCredentialsGrantType(OpenIdConnectRequest request)
        {
            // Note: client authentication is always enforced by OpenIddict before this action is invoked.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId, HttpContext.RequestAborted);

            if (application == null)
            {
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIdConnectConstants.Errors.InvalidClient,
                    ErrorDescription = T["The client application is unknown."]
                }));
            }

            var identity = new ClaimsIdentity(
                OpenIdConnectServerDefaults.AuthenticationScheme,
                OpenIdConnectConstants.Claims.Name,
                OpenIdConnectConstants.Claims.Role);

            identity.AddClaim(OpenIdConnectConstants.Claims.Subject, application.ClientId);
            identity.AddClaim(OpenIdConnectConstants.Claims.Name,
                              await _applicationManager.GetDisplayNameAsync(application, HttpContext.RequestAborted),
                              OpenIdConnectConstants.Destinations.AccessToken,
                              OpenIdConnectConstants.Destinations.IdentityToken);

            foreach (var roleName in application.RoleNames)
            {
                identity.AddClaim(identity.RoleClaimType, roleName,
                                  OpenIdConnectConstants.Destinations.AccessToken,
                                  OpenIdConnectConstants.Destinations.IdentityToken);

                foreach (var claim in await _roleManager.GetClaimsAsync(await _roleManager.FindByIdAsync(roleName)))
                {
                    identity.AddClaim(claim.Type, claim.Value, OpenIdConnectConstants.Destinations.AccessToken,
                                      OpenIdConnectConstants.Destinations.IdentityToken);
                }
            }

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

            ticket.SetResources(await GetResourcesAsync(request));

            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
        public async Task <IActionResult> Authorize(OpenIdConnectRequest request)
        {
            Debug.Assert(request.IsAuthorizationRequest(),
                         "The OpenIddict binder for ASP.NET Core MVC is not registered. " +
                         "Make sure services.AddOpenIddict().AddServer().UseMvc() is correctly called.");

            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(BadRequest("Details concerning the calling client application cannot be found in the database"));
            }

            // Flow the request_id to allow OpenIddict to restore
            // the original authorization request from the cache.
            return(Redirect($"/Login?ApplicationName={await _applicationManager.GetDisplayNameAsync(application)}&RequestId={request.RequestId}&Scope={request.Scope}"));
        }
        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
                }));
            }
        }
예제 #10
0
        public virtual async Task <IActionResult> Authorize([RequestUser] User requestUser,
                                                            [FromQuery] string returnUrl = "")
        {
            if (requestUser == null)
            {
                return(Redirect("/OpenId/Login?ReturnUrl=" + returnUrl));
            }
            // Identity cookie that is not valid anymore (e.g. deleted user), still gets through
            // the [Authorize] attribute by design. Check that user actually exists.
            var user = await _userManager.GetUserAsync(HttpContext.User);

            if (user == null)
            {
                await _signInManager.SignOutAsync();

                return(Redirect(HttpContext.Request.GetEncodedUrl()));
            }

            // Extract the authorization request from the ASP.NET environment.
            var request = HttpContext.GetOpenIdConnectRequest();

            // Retrieve the application details from the database.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(RedirectToAction(nameof(ErrorController.Error), nameof(ErrorController), new { message = FatalErrors.InvalidClient }));
            }

            // Check if the application is official (registered in settings) and
            // accept any request by default
            if (_officialApplications.Value.Any(x => x.Value.ClientId == request.ClientId))
            {
                return(await Accept());
            }

            var appName = await _applicationManager.GetDisplayNameAsync(application);

            var inputs       = "";
            var hiddenParams = new Dictionary <string, string> {
                { "request_id", request.RequestId }
            };

            foreach (var item in hiddenParams)
            {
                var key   = WebUtility.HtmlEncode(item.Key);
                var value = WebUtility.HtmlEncode(item.Value);
                inputs = inputs + $@"<input type=""hidden"" name=""{key}"" value=""{value}"" />";
            }

            // TODO: Anti forgery token for Accept and Deny
            var data = JsonConvert.SerializeObject(new
            {
                Display          = request.GetParameter("display"),
                Scopes           = request.GetScopes().ToList(),
                FormMethod       = "POST",
                FormActionAccept = Url.Action(nameof(Accept)),
                FormActionDeny   = Url.Action(nameof(Deny)),
                ApplicationName  = appName,
                FormData         = hiddenParams
            }, _mvcJsonOptions.SerializerSettings);

            return(new ContentResult()
            {
                Content = $@"<!DOCTYPE html>
                    <html>
                    <head>
                    <script>var OPENID_AUTHORIZE_PAGE = {data};</script>
                    {_brandingHtml?.Authorize}
                    </head>
                    <body>
                    <form enctype=""application/x-www-form-urlencoded"" method=""POST"">
                    {inputs}
                    <div>{WebUtility.HtmlEncode(appName)}</div>
                    <button formaction=""{Url.Action(nameof(Accept))}"" type=""submit"" />ACCEPT</button>
                    <button formaction=""{Url.Action(nameof(Deny))}"" type=""submit"">DENY</button>
                ",
                ContentType = "text/html; charset=utf8"
            });
        }