Пример #1
0
        public async Task<IActionResult> Index(ConsentInputModel model)
        {
            // parse the return URL back to an AuthorizeRequest object
            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
            ConsentResponse response = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (model.Button == "no")
            {
                response = ConsentResponse.Denied;
            }
            // user clicked 'yes' - validate the data
            else if (model.Button == "yes" && model != null)
            {
                // if the user consented to some scope, build the response model
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    response = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = model.ScopesConsented
                    };
                }
                else
                {
                    ModelState.AddModelError("", "You must pick at least one permission.");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalid Selection");
            }

            if (response != null)
            {
                // communicate outcome of consent back to identityserver
                await _interaction.GrantConsentAsync(request, response);

                // todo: check for valid return URL?
                // redirect back to authorization endpoint
                return Redirect(model.ReturnUrl);
            }

            var vm = await BuildViewModelAsync(model.ReturnUrl, model);
            if (vm != null)
            {
                return View("Index", vm);
            }

            return View("Error");
        }
        /*****************************************/
        /* helper APIs for the ConsentController */
        /*****************************************/
        private async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            var result = new ProcessConsentResult();

            // validate return url is still valid
            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            if (request == null)
            {
                return(result);
            }

            ConsentResponse grantedConsent = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (model?.Button == "no")
            {
                grantedConsent = ConsentResponse.Denied;

                // emit event
                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested));
            }
            // user clicked 'yes' - validate the data
            else if (model?.Button == "yes")
            {
                // if the user consented to some scope, build the response model
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented;
                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = scopes.ToArray()
                    };

                    // emit event
                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested, grantedConsent.ScopesConsented, grantedConsent.RememberConsent));
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }

            if (grantedConsent != null)
            {
                // communicate outcome of consent back to identityserver
                await _interaction.GrantConsentAsync(request, grantedConsent);

                // indicate that's it ok to redirect back to authorization endpoint
                result.RedirectUri = model.ReturnUrl;
                result.ClientId    = request.ClientId;
            }
            else
            {
                // we need to redisplay the consent UI
                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Processes the consent logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException">Invalid PromptMode</exception>
        protected internal virtual async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (request.PromptMode != null &&
                request.PromptMode != OidcConstants.PromptModes.None &&
                request.PromptMode != OidcConstants.PromptModes.Consent)
            {
                Logger.LogError("Invalid prompt mode: {promptMode}", request.PromptMode);
                throw new ArgumentException("Invalid PromptMode");
            }

            var consentRequired = await Consent.RequiresConsentAsync(request.Subject, request.Client, request.RequestedScopes);

            if (consentRequired && request.PromptMode == OidcConstants.PromptModes.None)
            {
                Logger.LogInformation("Error: prompt=none requested, but consent is required.");

                return(new InteractionResponse
                {
                    Error = OidcConstants.AuthorizeErrors.ConsentRequired
                });
            }

            if (request.PromptMode == OidcConstants.PromptModes.Consent || consentRequired)
            {
                var response = new InteractionResponse();

                // did user provide consent
                if (consent == null)
                {
                    // user was not yet shown conset screen
                    response.IsConsent = true;
                    Logger.LogInformation("Showing consent: User has not yet consented");
                }
                else
                {
                    request.WasConsentShown = true;
                    Logger.LogTrace("Consent was shown to user");

                    // user was shown consent -- did they say yes or no
                    if (consent.Granted == false)
                    {
                        // no need to show consent screen again
                        // build access denied error to return to client
                        response.Error = OidcConstants.AuthorizeErrors.AccessDenied;
                        Logger.LogInformation("Error: User denied consent");
                    }
                    else
                    {
                        // double check that required scopes are in the list of consented scopes
                        var valid = request.ValidatedScopes.ValidateRequiredScopes(consent.ScopesConsented);
                        if (valid == false)
                        {
                            response.Error = OidcConstants.AuthorizeErrors.AccessDenied;
                            Logger.LogInformation("Error: User denied consent to required scopes");
                        }
                        else
                        {
                            // they said yes, set scopes they chose
                            request.ValidatedScopes.SetConsentedScopes(consent.ScopesConsented);
                            Logger.LogInformation("User consented to scopes: {scopes}", consent.ScopesConsented);

                            if (request.Client.AllowRememberConsent)
                            {
                                // remember consent
                                var scopes = Enumerable.Empty <string>();
                                if (consent.RememberConsent)
                                {
                                    // remember what user actually selected
                                    scopes = request.ValidatedScopes.GrantedResources.ToScopeNames();
                                    Logger.LogDebug("User indicated to remember consent for scopes: {scopes}", scopes);
                                }

                                await Consent.UpdateConsentAsync(request.Subject, request.Client, scopes);
                            }
                        }
                    }
                }

                return(response);
            }

            return(new InteractionResponse());
        }
Пример #4
0
        public async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            ProcessConsentResult result = new ProcessConsentResult();

            ConsentResponse grantedConsent = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (model.Button == "no")
            {
                grantedConsent = ConsentResponse.Denied;
            }
            // user clicked 'yes' - validate the data
            else if (model.Button == "yes" && model != null)
            {
                // if the user consented to some scope, build the response model
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    System.Collections.Generic.IEnumerable <string> scopes = model.ScopesConsented;
                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    grantedConsent = new ConsentResponse {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = scopes.ToArray()
                    };
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }

            if (grantedConsent != null)
            {
                // validate return url is still valid
                AuthorizationRequest request = await this._interaction.GetAuthorizationContextAsync(model.ReturnUrl);

                if (request == null)
                {
                    return(result);
                }

                // communicate outcome of consent back to identityserver
                await this._interaction.GrantConsentAsync(request, grantedConsent);

                // indicate that's it ok to redirect back to authorization endpoint
                result.RedirectUri = model.ReturnUrl;
            }
            else
            {
                // we need to redisplay the consent UI
                result.ViewModel = await this.BuildViewModelAsync(model.ReturnUrl, model);
            }

            return(result);
        }
Пример #5
0
        internal async Task <IEndpointResult> ProcessAuthorizeRequestAsync(NameValueCollection parameters, ClaimsPrincipal user, ConsentResponse consent)
        {
            if (user != null)
            {
                Logger.LogDebug("User in authorize request: {subjectId}", user.GetSubjectId());
            }
            else
            {
                Logger.LogDebug("No user present in authorize request");
            }

            // validate request
            var result = await _validator.ValidateAsync(parameters, user);

            if (result.IsError)
            {
                return(await CreateErrorResultAsync(
                           "Request validation failed",
                           result.ValidatedRequest,
                           result.Error,
                           result.ErrorDescription));
            }

            var request = result.ValidatedRequest;

            LogRequest(request);

            // determine user interaction
            var interactionResult = await _interactionGenerator.ProcessInteractionAsync(request, consent);

            if (interactionResult.IsError)
            {
                return(await CreateErrorResultAsync("Interaction generator error", request, interactionResult.Error, interactionResult.ErrorDescription, false));
            }
            if (interactionResult.IsLogin)
            {
                return(new LoginPageResult(request));
            }
            if (interactionResult.IsConsent)
            {
                return(new ConsentPageResult(request));
            }
            if (interactionResult.IsRedirect)
            {
                return(new CustomRedirectResult(request, interactionResult.RedirectUrl));
            }

            var response = await _authorizeResponseGenerator.CreateResponseAsync(request);

            await RaiseResponseEventAsync(response);

            LogResponse(response);

            return(new AuthorizeResult(response));
        }
Пример #6
0
 public ConsentResult(string requestId, ConsentResponse response)
 {
     _requestId = requestId;
     _response  = response;
 }
        /// <summary>
        /// Processes the interaction logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        public virtual async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            Logger.LogTrace("ProcessInteractionAsync");

            if (consent != null && consent.Granted == false && consent.Error.HasValue && request.Subject.IsAuthenticated() == false)
            {
                // special case when anonymous user has issued an error prior to authenticating
                Logger.LogInformation("Error: User consent result: {error}", consent.Error);

                var error = consent.Error switch
                {
                    AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired,
                    AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired,
                    AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired,
                    AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired,
                    _ => OidcConstants.AuthorizeErrors.AccessDenied
                };

                return(new InteractionResponse
                {
                    Error = error,
                    ErrorDescription = consent.ErrorDescription
                });
            }

            var result = await ProcessLoginAsync(request);

            if (!result.IsLogin && !result.IsError && !result.IsRedirect)
            {
                result = await ProcessConsentAsync(request, consent);
            }

            if ((result.IsLogin || result.IsConsent || result.IsRedirect) && request.PromptModes.Contains(OidcConstants.PromptModes.None))
            {
                // prompt=none means do not show the UI
                Logger.LogInformation("Changing response to LoginRequired: prompt=none was requested");
                result = new InteractionResponse
                {
                    Error = result.IsLogin ? OidcConstants.AuthorizeErrors.LoginRequired :
                            result.IsConsent ? OidcConstants.AuthorizeErrors.ConsentRequired :
                            OidcConstants.AuthorizeErrors.InteractionRequired
                };
            }

            return(result);
        }
Пример #8
0
        private async Task <ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)
        {
            var result = new ProcessConsentResult();

            var request = await _interactionService.GetAuthorizationContextAsync(model.UserCode);

            if (request == null)
            {
                return(result);
            }

            ConsentResponse consentResponse = null;

            if (model.Button == "no")
            {
                consentResponse = new ConsentResponse {
                    Error = AuthorizationError.AccessDenied
                };

                await _eventService.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
            }
            else if (model.Button == "yes")
            {
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented;

                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(scope => scope != IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    consentResponse = new ConsentResponse
                    {
                        RememberConsent       = model.RememberConsent,
                        ScopesValuesConsented = scopes.ToArray(),
                        Description           = model.Description
                    };

                    await _eventService.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, consentResponse.ScopesValuesConsented, consentResponse.RememberConsent));
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }

            if (consentResponse != null)
            {
                await _interactionService.HandleRequestAsync(model.UserCode, consentResponse);

                result.RedirectUri = model.ReturnUrl;

                result.Client = request.Client;
            }
            else
            {
                result.ViewModel = await BuildViewModelAsync(model.UserCode, model);
            }

            return(result);
        }
Пример #9
0
        private async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            var result = new ProcessConsentResult();

            // 验证URL是否有效
            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            if (request == null)
            {
                return(result);
            }
            ConsentResponse grantedConsent = null;

            if (model.Button == "no")
            {
                grantedConsent = ConsentResponse.Denied;
            }
            else if (model.Button == "yes")
            {
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented.ToList();

                    //获取所有
                    var identitResource = await _resourceStore.FindIdentityResourcesByScopeAsync(request.ScopesRequested);

                    //if (identitResource != null && identitResource.Any())
                    //{
                    //    //获取不显示在界面,但是必须项Required的
                    //    identitResource.Where(i => !i.ShowInDiscoveryDocument && i.Required).ToList()
                    //        .ForEach(f => { scopes.Add(f.Name); });
                    //}

                    //if (ConsentOptions.EnableOfflineAccess == false)
                    //{
                    //    scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);
                    //}

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = scopes.ToArray()
                    };
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }
            if (grantedConsent != null)
            {
                // 把同意的结果发送给 identityserver
                await _interaction.GrantConsentAsync(request, grantedConsent);

                // indicate that's it ok to redirect back to authorization endpoint
                result.RedirectUri = model.ReturnUrl;
                //var ck = new Uri(model.ReturnUrl);
                //result.RedirectUri = "http://localhost:5006/";
                result.ClientId = request.ClientId;

                var id     = _configurationDbContext.Clients.ToList().Find(f => f.ClientId == request.ClientId).Id;
                var entity = _applicationDbContext.applicationUseAuthorizations.FirstOrDefault(_ => _.ClientId == id);
                ////判断是否授权过
                //if (entity != null && !entity.Enabled)
                //{
                //    entity.Enabled = true;
                //    _applicationDbContext.Update(entity);
                //    _applicationDbContext.SaveChanges();
                //}
                //else
                //{
                //    //给用户添加第三方授权信息
                //    await _applicationDbContext.AddAsync(new ApplicationUseAuthorization
                //    {
                //        ClientId = id,
                //        Enabled = true
                //    });
                //    ////给用户添加第三方授权信息
                //    //_applicationDbContext.applicationUseAuthorizations.Add(new ApplicationUseAuthorization
                //    //{
                //    //    ClientId = id,
                //    //    Enabled = true
                //    //});
                //    //_applicationDbContext.SaveChanges();
                //}
            }
            else
            {
                // we need to redisplay the consent UI
                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);
            }
            return(result);
        }
        /// <summary>
        /// Processes the interaction logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        public virtual async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            Logger.LogTrace("ProcessInteractionAsync");

            if (consent != null && consent.Granted == false && consent.Error.HasValue && request.Subject.IsAuthenticated() == false)
            {
                // special case when anonymous user has issued an error prior to authenticating
                Logger.LogInformation("Error: User consent result: {error}", consent.Error);

                var error = consent.Error switch
                {
                    AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired,
                    AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired,
                    AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired,
                    AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired,
                    _ => OidcConstants.AuthorizeErrors.AccessDenied
                };

                return(new InteractionResponse
                {
                    Error = error,
                    ErrorDescription = consent.ErrorDescription
                });
            }

            var result = await ProcessLoginAsync(request);

            if (result.IsLogin || result.IsError)
            {
                return(result);
            }

            result = await ProcessConsentAsync(request, consent);

            return(result);
        }
        public override async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            {
                var response = await base.ProcessInteractionAsync(request, consent);

                if (response.IsConsent || response.IsLogin || response.IsError)
                {
                    return(response);
                }

                //if (!request.Subject.HasClaim(c => c.Type == "TenantId" && c.Value != "0"))
                //    return new InteractionResponse
                //    {
                //        RedirectUrl = "/Company"
                //    };

                return(new InteractionResponse());
            }
        }
Пример #12
0
        public async Task <IActionResult> OnPost()
        {
            var request = await interaction.GetAuthorizationContextAsync(ReturnUrl);

            if (request == null)
            {
                throw new ApplicationException($"No consent request matching request: {ReturnUrl}");
            }

            ConsentResponse grantedConsent = null;

            if (string.Equals(Input.Button, "NO", StringComparison.OrdinalIgnoreCase))
            {
                grantedConsent = new ConsentResponse {
                    Error = AuthorizationError.AccessDenied
                };

                await events.RaiseAsync(
                    new ConsentDeniedEvent(
                        User.GetSubjectId(),
                        request.Client.ClientId,
                        request.ValidatedResources.RawScopeValues));
            }
            else if (string.Equals(Input.Button, "YES", StringComparison.OrdinalIgnoreCase))
            {
                if (Input.ScopesConsented != null && Input.ScopesConsented.Any())
                {
                    var scopes = Input.ScopesConsented;

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent = Input.RememberConsent, ScopesValuesConsented = scopes.ToArray()
                    };

                    await events.RaiseAsync(
                        new ConsentGrantedEvent(
                            User.GetSubjectId(),
                            request.Client.ClientId,
                            request.ValidatedResources.RawScopeValues,
                            grantedConsent.ScopesValuesConsented,
                            grantedConsent.RememberConsent));
                }
                else
                {
                    ModelState.AddModelError(string.Empty, T["MustChooseOneErrorMessage"]);
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, T["InvalidSelectionErrorMessage"]);
            }

            if (grantedConsent != null)
            {
                await interaction.GrantConsentAsync(request, grantedConsent);

                return(RedirectTo(ReturnUrl));
            }
            else
            {
                await SetupModelAsync(Input);
            }

            return(Page());
        }
Пример #13
0
 public async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
 {
     return(await Task.FromResult <InteractionResponse>(null));
 }
Пример #14
0
 public Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
 {
     throw new NotImplementedException();
 }
Пример #15
0
    public async Task <IActionResult> OnPost()
    {
        // validate return url is still valid
        var request = await _interaction.GetAuthorizationContextAsync(Input.ReturnUrl);

        if (request == null)
        {
            return(RedirectToPage("/Home/Error/Index"));
        }

        ConsentResponse grantedConsent = null;

        // user clicked 'no' - send back the standard 'access_denied' response
        if (Input?.Button == "no")
        {
            grantedConsent = new ConsentResponse {
                Error = AuthorizationError.AccessDenied
            };

            // emit event
            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
        }
        // user clicked 'yes' - validate the data
        else if (Input?.Button == "yes")
        {
            // if the user consented to some scope, build the response model
            if (Input.ScopesConsented != null && Input.ScopesConsented.Any())
            {
                var scopes = Input.ScopesConsented;
                if (ConsentOptions.EnableOfflineAccess == false)
                {
                    scopes = scopes.Where(x => x != Duende.IdentityServer.IdentityServerConstants.StandardScopes.OfflineAccess);
                }

                grantedConsent = new ConsentResponse
                {
                    RememberConsent       = Input.RememberConsent,
                    ScopesValuesConsented = scopes.ToArray(),
                    Description           = Input.Description
                };

                // emit event
                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
            }
            else
            {
                ModelState.AddModelError("", ConsentOptions.MustChooseOneErrorMessage);
            }
        }
        else
        {
            ModelState.AddModelError("", ConsentOptions.InvalidSelectionErrorMessage);
        }

        if (grantedConsent != null)
        {
            // communicate outcome of consent back to identityserver
            await _interaction.GrantConsentAsync(request, grantedConsent);

            // redirect back to authorization endpoint
            if (request.IsNativeClient() == true)
            {
                // The client is native, so this change in how to
                // return the response is for better UX for the end user.
                return(this.LoadingPage(Input.ReturnUrl));
            }

            return(Redirect(Input.ReturnUrl));
        }

        // we need to redisplay the consent UI
        View = await BuildViewModelAsync(Input.ReturnUrl, Input);

        return(Page());
    }
Пример #16
0
 protected internal override Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
 {
     if (ProcessConsentResponse != null)
     {
         return(Task.FromResult(ProcessConsentResponse));
     }
     return(base.ProcessConsentAsync(request, consent));
 }
Пример #17
0
        public async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            var result = new ProcessConsentResult();

            ConsentResponse grantedConsent = null;

            switch (model.Button)
            {
            case "no":
            {
                grantedConsent = ConsentResponse.Denied;
                break;
            }

            case "yes" when model.ScopesConsented != null && model.ScopesConsented.Any():
            {
                var scopes = model.ScopesConsented;
                if (_identityServerCommonOptions.EnableOfflineAccess == false)
                {
                    scopes = scopes.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess);
                }

                grantedConsent = new ConsentResponse
                {
                    RememberConsent = model.RememberConsent,
                    ScopesConsented = scopes.ToArray()
                };
                break;
            }

            case "yes":
            {
                result.ValidationError = _identityServerCommonOptions.MustChooseOneErrorMessage;
                break;
            }

            default:
            {
                result.ValidationError = _identityServerCommonOptions.InvalidSelectionErrorMessage;
                break;
            }
            }

            if (grantedConsent != null)
            {
                // validate return url is still valid
                var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

                if (request == null)
                {
                    return(result);
                }

                // communicate outcome of consent back to IdentityServer
                await _interaction.GrantConsentAsync(request, grantedConsent);

                // indicate that's it ok to redirect back to authorization endpoint
                result.RedirectUri = model.ReturnUrl;
            }
            else
            {
                // we need to redisplay the consent UI
                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);
            }

            return(result);
        }
Пример #18
0
        public async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            var result = new ProcessConsentResult();

            ConsentResponse grantedConsent = null;

            // 用户点击“否”发送标准的access_denied响应
            if (model.Button == "no")
            {
                grantedConsent = ConsentResponse.Denied;
            }
            // 用户单击“是”-验证数据
            else if (model.Button == "yes" && model != null)
            {
                // 如果用户同意某个范围,构建响应模型
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented;
                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = scopes.ToArray()
                    };
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }

            if (grantedConsent != null)
            {
                // 验证返回URL是否仍然有效
                var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

                if (request == null)
                {
                    return(result);
                }

                // 沟通的结果同意回到identityserver
                await _interaction.GrantConsentAsync(request, grantedConsent);

                // 指示重定向到授权终结点是可以的
                result.RedirectUri = model.ReturnUrl;
            }
            else
            {
                // 我们需要重新显示同意UI
                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);
            }

            return(result);
        }
        /// <summary>
        /// Processes the consent logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException">Invalid PromptMode</exception>
        protected internal virtual async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (request.PromptModes.Any() &&
                !request.PromptModes.Contains(OidcConstants.PromptModes.None) &&
                !request.PromptModes.Contains(OidcConstants.PromptModes.Consent))
            {
                Logger.LogError("Invalid prompt mode: {promptMode}", request.PromptModes.ToSpaceSeparatedString());
                throw new ArgumentException("Invalid PromptMode");
            }

            var consentRequired = await Consent.RequiresConsentAsync(request.Subject, request.Client, request.ValidatedResources.ParsedScopes);

            if (consentRequired && request.PromptModes.Contains(OidcConstants.PromptModes.None))
            {
                Logger.LogInformation("Error: prompt=none requested, but consent is required.");

                return(new InteractionResponse
                {
                    Error = OidcConstants.AuthorizeErrors.ConsentRequired
                });
            }

            if (request.PromptModes.Contains(OidcConstants.PromptModes.Consent) || consentRequired)
            {
                var response = new InteractionResponse();

                // did user provide consent
                if (consent == null)
                {
                    // user was not yet shown conset screen
                    response.IsConsent = true;
                    Logger.LogInformation("Showing consent: User has not yet consented");
                }
                else
                {
                    request.WasConsentShown = true;
                    Logger.LogTrace("Consent was shown to user");

                    // user was shown consent -- did they say yes or no
                    if (consent.Granted == false)
                    {
                        // no need to show consent screen again
                        // build error to return to client
                        Logger.LogInformation("Error: User consent result: {error}", consent.Error);

                        var error = consent.Error switch
                        {
                            AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired,
                            AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired,
                            AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired,
                            AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired,
                            _ => OidcConstants.AuthorizeErrors.AccessDenied
                        };

                        response.Error            = error;
                        response.ErrorDescription = consent.ErrorDescription;
                    }
                    else
                    {
                        // double check that required scopes are in the list of consented scopes
                        var requiredScopes = request.ValidatedResources.GetRequiredScopeValues();
                        var valid          = requiredScopes.All(x => consent.ScopesValuesConsented.Contains(x));
                        if (valid == false)
                        {
                            response.Error = OidcConstants.AuthorizeErrors.AccessDenied;
                            Logger.LogInformation("Error: User denied consent to required scopes");
                        }
                        else
                        {
                            // they said yes, set scopes they chose
                            request.Description        = consent.Description;
                            request.ValidatedResources = request.ValidatedResources.Filter(consent.ScopesValuesConsented);
                            Logger.LogInformation("User consented to scopes: {scopes}", consent.ScopesValuesConsented);

                            if (request.Client.AllowRememberConsent)
                            {
                                // remember consent
                                var parsedScopes = Enumerable.Empty <ParsedScopeValue>();
                                if (consent.RememberConsent)
                                {
                                    // remember what user actually selected
                                    parsedScopes = request.ValidatedResources.ParsedScopes;
                                    Logger.LogDebug("User indicated to remember consent for scopes: {scopes}", request.ValidatedResources.RawScopeValues);
                                }

                                await Consent.UpdateConsentAsync(request.Subject, request.Client, parsedScopes);
                            }
                        }
                    }
                }

                return(response);
            }

            return(new InteractionResponse());
        }
        public override async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            {
                var response = await base.ProcessInteractionAsync(request, consent);

                if (response.IsConsent || response.IsLogin || response.IsError)
                {
                    return(response);
                }
                if (!request.Subject.HasClaim(c => c.Type == "tid" && c.Value != "0"))
                {
                    return new InteractionResponse
                           {
                               RedirectUrl = "/Tenants"
                           }
                }
                ;
                if (!request.Subject.HasClaim(c => c.Type == "companyProfileInComplete"))
                {
                    return new InteractionResponse
                           {
                               RedirectUrl = "/OnBoarding"
                           }
                }
                ;
                return(new InteractionResponse());
            }
        }
    }
}
Пример #21
0
        public async Task <IActionResult> Index([FromBody] ConsentInputViewModel model)
        {
            // parse the return URL back to an AuthorizeRequest object
            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            ConsentResponse response = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (model.YesButtonClicked == false)
            {
                response = ConsentResponse.Denied;
            }
            // user clicked 'yes' - validate the data
            else if (model.YesButtonClicked == true)
            {
                // if the user consented to some scope, build the response model
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    response = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = model.ScopesConsented
                    };
                }
                else
                {
                    ModelState.AddModelError("", "You must pick at least one permission.");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalid Selection");
            }

            if (response != null)
            {
                // communicate outcome of consent back to identityserver
                await _interaction.GrantConsentAsync(request, response);

                // redirect back to authorization endpoint
                return(Ok(model.ReturnUrl));
            }

            var vm = await BuildViewModelAsync(model.ReturnUrl, model);

            if (vm != null)
            {
                var serializedVm = JsonConvert.SerializeObject(vm);
                return(View("Index", serializedVm));
            }

            var errorsJson = new JsonErrorResponse
            {
                Messages = ModelState.Values
                           .SelectMany(x => x.Errors)
                           .Select(x => x.ErrorMessage)
                           .ToArray()
            };
            var errors = new BadRequestObjectResult(errorsJson);

            return(BadRequest(errors));
        }
Пример #22
0
        internal async Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.PromptMode != null &&
                request.PromptMode != OidcConstants.PromptModes.None &&
                request.PromptMode != OidcConstants.PromptModes.Consent)
            {
                throw new ArgumentException("Invalid PromptMode");
            }

            var consentRequired = await _consent.RequiresConsentAsync(request.Client, request.Subject, request.RequestedScopes);

            if (consentRequired && request.PromptMode == OidcConstants.PromptModes.None)
            {
                _logger.LogInformation("Prompt=none requested, but consent is required.");

                return(new InteractionResponse
                {
                    Error = new AuthorizeError
                    {
                        ErrorType = ErrorTypes.Client,
                        Error = OidcConstants.AuthorizeErrors.ConsentRequired,
                        ResponseMode = request.ResponseMode,
                        ErrorUri = request.RedirectUri,
                        State = request.State
                    }
                });
            }

            if (request.PromptMode == OidcConstants.PromptModes.Consent || consentRequired)
            {
                var response = new InteractionResponse();

                // did user provide consent
                if (consent == null)
                {
                    // user was not yet shown conset screen
                    response.IsConsent = true;
                }
                else
                {
                    request.WasConsentShown = true;

                    // user was shown consent -- did they say yes or no
                    if (consent.Granted == false)
                    {
                        // no need to show consent screen again
                        // build access denied error to return to client
                        response.Error = new AuthorizeError
                        {
                            ErrorType    = ErrorTypes.Client,
                            Error        = OidcConstants.AuthorizeErrors.AccessDenied,
                            ResponseMode = request.ResponseMode,
                            ErrorUri     = request.RedirectUri,
                            State        = request.State
                        };
                    }
                    else
                    {
                        // double check that required scopes are in the list of consented scopes
                        var valid = request.ValidatedScopes.ValidateRequiredScopes(consent.ScopesConsented);
                        if (valid == false)
                        {
                            response.Error = new AuthorizeError
                            {
                                ErrorType    = ErrorTypes.Client,
                                Error        = OidcConstants.AuthorizeErrors.AccessDenied,
                                ResponseMode = request.ResponseMode,
                                ErrorUri     = request.RedirectUri,
                                State        = request.State
                            };
                        }
                        else
                        {
                            // they said yes, set scopes they chose
                            request.ValidatedScopes.SetConsentedScopes(consent.ScopesConsented);

                            if (request.Client.AllowRememberConsent)
                            {
                                // remember consent
                                var scopes = Enumerable.Empty <string>();
                                if (consent.RememberConsent)
                                {
                                    // remember what user actually selected
                                    scopes = request.ValidatedScopes.GrantedScopes.Select(x => x.Name);
                                }

                                await _consent.UpdateConsentAsync(request.Client, request.Subject, scopes);
                            }
                        }
                    }
                }

                return(response);
            }

            return(new InteractionResponse());
        }
        public Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            if (request.Subject?.IsAnonymous() == true)
            {
                return(Task.FromResult(new InteractionResponse {
                    IsLogin = true
                }));
            }

            return(_inner.ProcessInteractionAsync(request, consent));
        }
        /// <summary>
        /// Processes the interaction logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        public virtual async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            _logger.LogTrace("ProcessInteractionAsync");

            var result = await ProcessLoginAsync(request);

            if (result.IsLogin || result.IsError)
            {
                return(result);
            }

            return(await ProcessConsentAsync(request, consent));
        }
Пример #25
0
    public async Task <DeviceFlowInteractionResult> HandleRequestAsync(string userCode, ConsentResponse consent)
    {
        if (userCode == null)
        {
            throw new ArgumentNullException(nameof(userCode));
        }
        if (consent == null)
        {
            throw new ArgumentNullException(nameof(consent));
        }

        var deviceAuth = await _devices.FindByUserCodeAsync(userCode);

        if (deviceAuth == null)
        {
            return(LogAndReturnError("Invalid user code", "Device authorization failure - user code is invalid"));
        }

        var client = await _clients.FindEnabledClientByIdAsync(deviceAuth.ClientId);

        if (client == null)
        {
            return(LogAndReturnError("Invalid client", "Device authorization failure - requesting client is invalid"));
        }

        var subject = await _session.GetUserAsync();

        if (subject == null)
        {
            return(LogAndReturnError("No user present in device flow request", "Device authorization failure - no user found"));
        }

        var sid = await _session.GetSessionIdAsync();

        deviceAuth.IsAuthorized     = true;
        deviceAuth.Subject          = subject;
        deviceAuth.SessionId        = sid;
        deviceAuth.Description      = consent.Description;
        deviceAuth.AuthorizedScopes = consent.ScopesValuesConsented;

        // TODO: Device Flow - Record consent template
        if (consent.RememberConsent)
        {
            //var consentRequest = new ConsentRequest(request, subject);
            //await _consentMessageStore.WriteAsync(consentRequest.Id, new Message<ConsentResponse>(consent, _clock.UtcNow.UtcDateTime));
        }

        await _devices.UpdateByUserCodeAsync(userCode, deviceAuth);

        return(new DeviceFlowInteractionResult());
    }
Пример #26
0
        public override async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            var result = await base.ProcessInteractionAsync(request, consent);

            //用户账户分组设置
            //var client = request.ClientId;
            //var clientGroup = GetClientGroup(client);
            //var user = ??????????????;
            //if (user.IsAuthenticated() && !result.IsConsent && !user.Claims.Any(x => x.Type == "client_group" && x.Value == clientGroup))
            //{
            //    result.IsLogin = true;
            //}

            var checkLoginClients = new[] { "netcore.client3", "netcore.client4", "netfx.client3", "netfx.client4" };

            if ((checkLoginClients.Contains(request.ClientId)) && (request.Subject.Claims.FirstOrDefault(x => x.Type == request.ClientId) == null))
            {
                result.IsLogin = true;
            }

            return(result);
        }
Пример #27
0
    public async Task <IActionResult> OnPost()
    {
        var request = await _interaction.GetAuthorizationContextAsync(Input.UserCode);

        if (request == null)
        {
            return(RedirectToPage("/Error/Index"));
        }

        ConsentResponse grantedConsent = null;

        // user clicked 'no' - send back the standard 'access_denied' response
        if (Input.Button == "no")
        {
            grantedConsent = new ConsentResponse
            {
                Error = AuthorizationError.AccessDenied
            };

            // emit event
            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
        }
        // user clicked 'yes' - validate the data
        else if (Input.Button == "yes")
        {
            // if the user consented to some scope, build the response model
            if (Input.ScopesConsented != null && Input.ScopesConsented.Any())
            {
                var scopes = Input.ScopesConsented;
                if (ConsentOptions.EnableOfflineAccess == false)
                {
                    scopes = scopes.Where(x => x != Duende.IdentityServer.IdentityServerConstants.StandardScopes.OfflineAccess);
                }

                grantedConsent = new ConsentResponse
                {
                    RememberConsent       = Input.RememberConsent,
                    ScopesValuesConsented = scopes.ToArray(),
                    Description           = Input.Description
                };

                // emit event
                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
            }
            else
            {
                ModelState.AddModelError("", ConsentOptions.MustChooseOneErrorMessage);
            }
        }
        else
        {
            ModelState.AddModelError("", ConsentOptions.InvalidSelectionErrorMessage);
        }

        if (grantedConsent != null)
        {
            // communicate outcome of consent back to identityserver
            await _interaction.HandleRequestAsync(Input.UserCode, grantedConsent);

            // indicate that's it ok to redirect back to authorization endpoint
            return(RedirectToPage("/Device/Success"));
        }

        // we need to redisplay the consent UI
        View = await BuildViewModelAsync(Input.UserCode, Input);

        return(Page());
    }
Пример #28
0
        /*****************************************/
        /* helper APIs for the ConsentController */
        /*****************************************/
        private async Task <ProcessConsentResult> ProcessConsent(ConsentInputModel model)
        {
            var result = new ProcessConsentResult();

            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            if (request == null)
            {
                return(result);
            }

            ConsentResponse grantedConsent = null;

            if (model.Button == "no")
            {
                grantedConsent = ConsentResponse.Denied;

                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), result.ClientId, request.ScopesRequested));
            }
            else if (model.Button == "yes" && model != null)
            {
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented;
                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent = model.RememberConsent,
                        ScopesConsented = scopes.ToArray()
                    };

                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested, grantedConsent.ScopesConsented, grantedConsent.RememberConsent));
                }
                else
                {
                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;
                }
            }
            else
            {
                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;
            }

            if (grantedConsent != null)
            {
                await _interaction.GrantConsentAsync(request, grantedConsent);

                result.RedirectUri = model.ReturnUrl;
                result.ClientId    = request.ClientId;
            }
            else
            {
                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);
            }

            return(result);
        }
Пример #29
0
        /// <summary>
        /// Processes the interaction logic.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="consent">The consent.</param>
        /// <returns></returns>
        public virtual async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            Logger.LogTrace("ProcessInteractionAsync");

            if (consent != null && consent.Granted == false && request.Subject.IsAuthenticated() == false)
            {
                // special case when anonymous user has issued a deny prior to authenticating
                Logger.LogInformation("Error: User denied consent");
                return(new InteractionResponse
                {
                    Error = OidcConstants.AuthorizeErrors.AccessDenied
                });
            }

            var result = await ProcessLoginAsync(request);

            if (result.IsLogin || result.IsError)
            {
                return(result);
            }

            result = await ProcessConsentAsync(request, consent);

            return(result);
        }
Пример #30
0
        public override async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            var result = await base.ProcessInteractionAsync(request, consent);

            if (!result.IsLogin && !result.IsConsent && !result.IsRedirect && !result.IsError)
            {
                var tenantAcr   = request.GetTenantAcrValue();
                var claim       = request.Subject?.Claims.SingleOrDefault(c => c.Type == AppClaimTypes.Tenant);
                var tenantClaim = claim?.Value.ToLowerInvariant();
                if (!string.IsNullOrEmpty(tenantAcr) && !string.IsNullOrEmpty(tenantClaim))
                {
                    Logger.LogInformation("Validating tenant. Cookie tenant: {0}, acr tenant: {1}", tenantClaim, tenantAcr);
                    return(new InteractionResponse {
                        IsLogin = tenantClaim != tenantAcr
                    });
                }
            }

            return(result);
        }
Пример #31
0
        private async Task <ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)
        {
            var result = new ProcessConsentResult();

            var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);

            if (request == null)
            {
                return(result);
            }

            ConsentResponse grantedConsent = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (model.Button == "no")
            {
                grantedConsent = new ConsentResponse {
                    Error = AuthorizationError.AccessDenied
                };

                // emit event
                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));
            }
            // user clicked 'yes' - validate the data
            else if (model.Button == "yes")
            {
                // if the user consented to some scope, build the response model
                if (model.ScopesConsented != null && model.ScopesConsented.Any())
                {
                    var scopes = model.ScopesConsented;
                    if (ConsentOptions.EnableOfflineAccess == false)
                    {
                        scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess);
                    }

                    grantedConsent = new ConsentResponse
                    {
                        RememberConsent       = model.RememberConsent,
                        ScopesValuesConsented = scopes.ToArray(),
                        Description           = model.Description
                    };

                    // emit event
                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));
                }
                else
                {
                    result.ValidationError = _sharedLocalizer["You must pick at least one permission"];
                }
            }
            else
            {
                result.ValidationError = _sharedLocalizer["Invalid selection"];
            }

            if (grantedConsent != null)
            {
                // communicate outcome of consent back to identityserver
                await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);

                // indicate that's it ok to redirect back to authorization endpoint
                result.RedirectUri = model.ReturnUrl;
                result.Client      = request.Client;
            }
            else
            {
                // we need to redisplay the consent UI
                result.ViewModel = await BuildViewModelAsync(model.UserCode, model);
            }

            return(result);
        }
 public ConsentResult(string requestId, ConsentResponse response)
 {
     _requestId = requestId;
     _response = response;
 }