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); }
/// <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()); }
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); }
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)); }
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); }
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); }
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()); } }
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()); }
public async Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { return(await Task.FromResult <InteractionResponse>(null)); }
public Task <InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { throw new NotImplementedException(); }
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()); }
protected internal override Task <InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null) { if (ProcessConsentResponse != null) { return(Task.FromResult(ProcessConsentResponse)); } return(base.ProcessConsentAsync(request, consent)); }
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); }
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()); } } } }
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)); }
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)); }
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()); }
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); }
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()); }
/*****************************************/ /* 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); }
/// <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); }
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); }
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); }