コード例 #1
0
        public async Task <IActionResult> Consent([FromForm] InputModel input)
        {
            var request = await _interaction.GetLoginRequestByInternalIdAsync(input.Id);

            var viewModel = BuildViewModelAsync(request, input.Id, input);

            CompleteBackchannelLoginRequest result = null;

            // user clicked 'no' - send back the standard 'access_denied' response
            if (input.Button == "no")
            {
                result = new CompleteBackchannelLoginRequest(input.Id);

                // emit event
                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues))
                .ConfigureAwait(false);
            }
            // 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 != StandardScopes.OfflineAccess);
                    }

                    result = new CompleteBackchannelLoginRequest(input.Id)
                    {
                        ScopesValuesConsented = scopes.ToArray(),
                        Description           = input.Description
                    };

                    // emit event
                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, result.ScopesValuesConsented, false))
                    .ConfigureAwait(false);;
                }
                else
                {
                    ModelState.AddModelError(string.Empty, ConsentOptions.MustChooseOneErrorMessage);
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, ConsentOptions.InvalidSelectionErrorMessage);
            }

            if (result != null)
            {
                // communicate outcome of consent back to identityserver
                await _interaction.CompleteLoginRequestAsync(result);

                return(RedirectToPage("/Account/Manage/Ciba", new { area = "Identity" }));
            }

            return(View(viewModel));
        }
コード例 #2
0
    public async Task <IActionResult> OnPost()
    {
        // validate return url is still valid
        var request = await _interaction.GetLoginRequestByInternalIdAsync(Input.Id);

        if (request == null || request.Subject.GetSubjectId() != User.GetSubjectId())
        {
            _logger.LogError("Invalid id {id}", Input.Id);
            return(RedirectToPage("/Home/Error/Index"));
        }

        CompleteBackchannelLoginRequest result = null;

        // user clicked 'no' - send back the standard 'access_denied' response
        if (Input?.Button == "no")
        {
            result = new CompleteBackchannelLoginRequest(Input.Id);

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

                result = new CompleteBackchannelLoginRequest(Input.Id)
                {
                    ScopesValuesConsented = scopes.ToArray(),
                    Description           = Input.Description
                };

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

        if (result != null)
        {
            // communicate outcome of consent back to identityserver
            await _interaction.CompleteLoginRequestAsync(result);

            return(RedirectToPage("/Ciba/All"));
        }

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

        return(Page());
    }
コード例 #3
0
    /// <inheritdoc/>
    public async Task CompleteLoginRequestAsync(CompleteBackchannelLoginRequest competionRequest)
    {
        using var activity = Tracing.ServiceActivitySource.StartActivity("DefaultBackchannelAuthenticationInteractionService.CompleteLoginRequest");

        if (competionRequest == null)
        {
            throw new ArgumentNullException(nameof(competionRequest));
        }

        var request = await _requestStore.GetByInternalIdAsync(competionRequest.InternalId);

        if (request == null)
        {
            throw new InvalidOperationException("Invalid backchannel authentication request id.");
        }

        var subject = competionRequest.Subject ?? await _session.GetUserAsync();

        if (subject == null)
        {
            throw new InvalidOperationException("Invalid subject.");
        }

        if (subject.GetSubjectId() != request.Subject.GetSubjectId())
        {
            throw new InvalidOperationException($"User's subject id: '{subject.GetSubjectId()}' does not match subject id for backchannel authentication request: '{request.Subject.GetSubjectId()}'.");
        }

        var sid = (competionRequest.Subject == null) ?
                  await _session.GetSessionIdAsync() :
                  competionRequest.SessionId;

        if (competionRequest.ScopesValuesConsented != null)
        {
            var extra = competionRequest.ScopesValuesConsented.Except(request.RequestedScopes);
            if (extra.Any())
            {
                throw new InvalidOperationException("More scopes consented than originally requested.");
            }
        }

        var subjectClone = subject.Clone();

        if (!subject.HasClaim(x => x.Type == JwtClaimTypes.AuthenticationTime))
        {
            subjectClone.Identities.First().AddClaim(new Claim(JwtClaimTypes.AuthenticationTime, _systemClock.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer));
        }

        if (!subject.HasClaim(x => x.Type == JwtClaimTypes.IdentityProvider))
        {
            subjectClone.Identities.First().AddClaim(new Claim(JwtClaimTypes.IdentityProvider, IdentityServerConstants.LocalIdentityProvider));
        }

        request.IsComplete       = true;
        request.Subject          = subjectClone;
        request.SessionId        = sid;
        request.AuthorizedScopes = competionRequest.ScopesValuesConsented;
        request.Description      = competionRequest.Description;

        await _requestStore.UpdateByInternalIdAsync(competionRequest.InternalId, request);

        _logger.LogDebug("Successful update for backchannel authentication request id {id}", competionRequest.InternalId);
    }