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