Beispiel #1
0
        public async Task <IActionResult> Index(string returnUrl, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(returnUrl))
            {
                return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" }));
            }

            try
            {
                var unprotectedUrl = _dataProtector.Unprotect(returnUrl);
                var query          = unprotectedUrl.GetQueries().ToJObj();
                var clientId       = query.GetClientIdFromAuthorizationRequest();
                var oauthClient    = await _oauthClientRepository.FindOAuthClientById(clientId, cancellationToken);

                query = await _extractRequestHelper.Extract(Request.GetAbsoluteUriWithVirtualPath(), query, oauthClient);

                var scopes            = query.GetScopesFromAuthorizationRequest();
                var claims            = query.GetClaimsFromAuthorizationRequest();
                var claimDescriptions = new List <string>();
                if (claims != null && claims.Any())
                {
                    claimDescriptions = claims.Select(c => c.Name).ToList();
                }

                return(View(new ConsentsIndexViewModel(
                                _translationHelper.Translate(oauthClient.ClientNames, oauthClient.ClientId),
                                returnUrl,
                                oauthClient.AllowedScopes.Where(c => scopes.Contains(c.Name)).Select(s => s.Name),
                                claimDescriptions)));
            }
            catch (CryptographicException)
            {
                return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" }));
            }
        }
        public override async Task Validate(HandlerContext context, CancellationToken cancellationToken)
        {
            var openidClient = (OpenIdClient)context.Client;
            var clientId     = context.Request.RequestData.GetClientIdFromAuthorizationRequest();
            var scopes       = context.Request.RequestData.GetScopesFromAuthorizationRequest();
            var acrValues    = context.Request.RequestData.GetAcrValuesFromAuthorizationRequest();
            var prompt       = context.Request.RequestData.GetPromptFromAuthorizationRequest();
            var claims       = context.Request.RequestData.GetClaimsFromAuthorizationRequest();

            if (!scopes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(OAuth.ErrorMessages.MISSING_PARAMETER, OAuth.DTOs.AuthorizationRequestParameters.Scope));
            }

            if (!scopes.Contains(SIDOpenIdConstants.StandardScopes.OpenIdScope.Name))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.OPENID_SCOPE_MISSING);
            }

            var unsupportedScopes = scopes.Where(s => s != SIDOpenIdConstants.StandardScopes.OpenIdScope.Name && !context.Client.AllowedScopes.Any(sc => sc.Name == s));

            if (unsupportedScopes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(OAuth.ErrorMessages.UNSUPPORTED_SCOPES, string.Join(",", unsupportedScopes)));
            }

            if (context.User == null)
            {
                if (prompt == PromptParameters.None)
                {
                    throw new OAuthException(ErrorCodes.LOGIN_REQUIRED, OAuth.ErrorMessages.LOGIN_IS_REQUIRED);
                }

                throw new OAuthLoginRequiredException(await GetFirstAmr(acrValues, claims, openidClient, cancellationToken));
            }

            await _extractRequestHelper.Extract(context);

            await CommonValidate(context, cancellationToken);

            var responseTypes = context.Request.RequestData.GetResponseTypesFromAuthorizationRequest();
            var nonce         = context.Request.RequestData.GetNonceFromAuthorizationRequest();
            var redirectUri   = context.Request.RequestData.GetRedirectUriFromAuthorizationRequest();
            var maxAge        = context.Request.RequestData.GetMaxAgeFromAuthorizationRequest();
            var idTokenHint   = context.Request.RequestData.GetIdTokenHintFromAuthorizationRequest();

            if (string.IsNullOrWhiteSpace(redirectUri))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(OAuth.ErrorMessages.MISSING_PARAMETER, OAuth.DTOs.AuthorizationRequestParameters.RedirectUri));
            }

            if (responseTypes.Contains(TokenResponseParameters.IdToken) && string.IsNullOrWhiteSpace(nonce))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(OAuth.ErrorMessages.MISSING_PARAMETER, OpenID.DTOs.AuthorizationRequestParameters.Nonce));
            }

            if (maxAge != null)
            {
                if (DateTime.UtcNow > context.User.GetActiveSession().AuthenticationDateTime.AddSeconds(maxAge.Value))
                {
                    throw new OAuthLoginRequiredException(await GetFirstAmr(acrValues, claims, openidClient, cancellationToken));
                }
            }
            else if (openidClient.DefaultMaxAge != null && DateTime.UtcNow > context.User.GetActiveSession().AuthenticationDateTime.AddSeconds(openidClient.DefaultMaxAge.Value))
            {
                throw new OAuthLoginRequiredException(await GetFirstAmr(acrValues, claims, openidClient, cancellationToken));
            }

            if (!string.IsNullOrWhiteSpace(idTokenHint))
            {
                var payload = await ExtractIdTokenHint(idTokenHint, cancellationToken);

                if (context.User.Id != payload.GetSub())
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_SUBJECT_IDTOKENHINT);
                }

                if (!payload.GetAudiences().Contains(context.Request.IssuerName))
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.INVALID_AUDIENCE_IDTOKENHINT);
                }
            }

            switch (prompt)
            {
            case PromptParameters.Login:
                throw new OAuthLoginRequiredException(await GetFirstAmr(acrValues, claims, openidClient, cancellationToken));

            case PromptParameters.Consent:
                RedirectToConsentView(context);
                break;

            case PromptParameters.SelectAccount:
                throw new OAuthSelectAccountRequiredException();
            }

            if (!context.User.HasOpenIDConsent(clientId, scopes, claims))
            {
                RedirectToConsentView(context);
            }

            if (claims != null)
            {
                var idtokenClaims = claims.Where(cl => cl.Type == AuthorizationRequestClaimTypes.IdToken && cl.IsEssential && Jwt.Constants.USER_CLAIMS.Contains(cl.Name));
                var invalidClaims = idtokenClaims.Where(icl => !context.User.Claims.Any(cl => cl.Type == icl.Name && (icl.Values == null || !icl.Values.Any() || icl.Values.Contains(cl.Value))));
                if (invalidClaims.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(ErrorMessages.INVALID_CLAIMS, string.Join(",", invalidClaims.Select(i => i.Name))));
                }
            }
        }
Beispiel #3
0
        public async Task <IActionResult> Index(string returnUrl, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(returnUrl))
            {
                return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" }));
            }

            try
            {
                var unprotectedUrl = _dataProtector.Unprotect(returnUrl);
                var query          = unprotectedUrl.GetQueries().ToJObj();
                var clientId       = query.GetClientIdFromAuthorizationRequest();
                var oauthClient    = await _oauthClientRepository.FindOAuthClientById(clientId, cancellationToken);

                query = await _extractRequestHelper.Extract(Request.GetAbsoluteUriWithVirtualPath(), query, oauthClient);

                var claims            = query.GetClaimsFromAuthorizationRequest();
                var claimName         = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
                var consentId         = claims.Single(c => c.Name == _openbankingApiOptions.OpenBankingApiConsentClaimName).Values.First();
                var defaultLanguage   = CultureInfo.DefaultThreadCurrentUICulture != null ? CultureInfo.DefaultThreadCurrentUICulture.Name : _oauthHostOptions.DefaultCulture;
                var claimDescriptions = new List <string>();
                if (claims != null && claims.Any())
                {
                    claimDescriptions = claims.Select(c => c.Name).ToList();
                }

                var consent = await _accountAccessConsentRepository.Get(consentId, cancellationToken);

                if (consent == null)
                {
                    _logger.LogError($"Account Access Consent '{consentId}' doesn't exist");
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(Global.UnknownAccountAccessConsent, consentId));
                }

                var accounts = await _accountRepository.GetBySubject(claimName.Value, cancellationToken);

                return(View(new OpenBankingApiAccountConsentIndexViewModel(
                                returnUrl,
                                oauthClient.ClientNames.GetTranslation(defaultLanguage, oauthClient.ClientId),
                                accounts.Select(a => new OpenBankingApiAccountViewModel
                {
                    Id = a.AggregateId,
                    AccountSubType = a.AccountSubType.Name,
                    CashAccounts = a.Accounts.Select(ac => new OpenBankingApiCashAccountViewModel
                    {
                        Identification = ac.Identification,
                        SecondaryIdentification = ac.SecondaryIdentification
                    })
                }).ToList(),
                                new OpenBankingApiConsentAccountViewModel
                {
                    Id = consent.AggregateId,
                    ExpirationDateTime = consent.ExpirationDateTime,
                    Permissions = consent.Permissions.Select(p => p.Name)
                })));
            }
            catch (CryptographicException)
            {
                return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" }));
            }
        }