public async Task <IEndpointResult> ProcessAsync(HttpContext context) { if (!HttpMethods.IsGet(context.Request.Method)) { _logger.LogDebug($"Invalid HTTP method for authorize endpoint. Method: [{context.Request.Method}]"); return(new StatusCodeResult(HttpStatusCode.UnsupportedMediaType)); } _logger.LogDebug("Start authorize callback request"); var sessionParam = context.Request.Query[IdentityConstants.ChallengeIdQueryParameterName]; if (sessionParam.IsNullOrEmpty() || string.IsNullOrEmpty(sessionParam.FirstOrDefault())) { return(VCResponseHelpers.Error("missing_session", $"Empty {IdentityConstants.ChallengeIdQueryParameterName} param")); } var sessionId = sessionParam.FirstOrDefault(); var session = await _sessionStorageService.FindBySessionIdAsync(sessionId); if (session == null) { return(VCResponseHelpers.Error("invalid_session", "Cannot find corresponding session")); } if (session.ResponseType == "code") { var url = $"{session.RedirectUrl}?code={session.Id}"; _logger.LogDebug($"Code flow. Redirecting to {url}"); return(new RedirectResult(url)); } if (session.ResponseType == "token") { _logger.LogDebug("Token flow. Creating a token"); var presentation = session.Presentation; var issuer = context.GetIdentityServerIssuerUri(); var token = await _tokenIssuerService.IssueJwtAsync(10000, issuer, session.PresentationRecordId, presentation); if (_sessionStorageService.DeleteSession(session) == false) { _logger.LogError("Failed to delete a session"); } var url = $"{session.RedirectUrl}#access_token={token}&token_type=Bearer"; _logger.LogDebug($"Token flow. Redirecting to {url}"); return(new RedirectResult(url)); } _logger.LogError("Unknown response type"); return(VCResponseHelpers.Error("invalid_response_type", $"Unknown response type: [{session.ResponseType}]")); }
public async Task <IEndpointResult> ProcessAsync(HttpContext context) { _logger.LogDebug("Processing Authorize request"); NameValueCollection values; switch (context.Request.Method) { case "GET": values = context.Request.Query.AsNameValueCollection(); break; case "POST": if (!context.Request.HasFormContentType) { return(new StatusCodeResult(HttpStatusCode.UnsupportedMediaType)); } values = context.Request.Form.AsNameValueCollection(); break; default: return(new StatusCodeResult(HttpStatusCode.MethodNotAllowed)); } var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(VCResponseHelpers.Error(OidcConstants.TokenErrors.InvalidClient)); } var scopes = values.Get(IdentityConstants.ScopeParamName).Split(' '); if (!scopes.Contains(IdentityConstants.VCAuthnScopeName)) { return(VCResponseHelpers.Error(IdentityConstants.MissingVCAuthnScopeError, IdentityConstants.MissingVCAuthnScopeDesc)); } var presentationRecordId = values.Get(IdentityConstants.PresentationRequestConfigIDParamName); if (string.IsNullOrEmpty(presentationRecordId)) { return(VCResponseHelpers.Error(IdentityConstants.InvalidPresentationRequestConfigIDError, IdentityConstants.InvalidPresentationRequestConfigIDDesc)); } var redirectUrl = values.Get(IdentityConstants.RedirectUriParameterName); if (string.IsNullOrEmpty(redirectUrl)) { return(VCResponseHelpers.Error(IdentityConstants.InvalidRedirectUriError)); } if (clientResult.Client.RedirectUris.Any() && !clientResult.Client.RedirectUris.Contains(redirectUrl)) { return(VCResponseHelpers.Error(IdentityConstants.InvalidRedirectUriError)); } var responseType = values.Get(IdentityConstants.ResponseTypeUriParameterName); if (string.IsNullOrEmpty(responseType)) { responseType = IdentityConstants.DefaultResponseType; } var responseMode = values.Get(IdentityConstants.ResponseModeUriParameterName); if (string.IsNullOrEmpty(responseMode)) { responseMode = IdentityConstants.DefaultResponseMode; } PresentationConfiguration presentationRecord = await _presentationConfigurationService.GetAsync(presentationRecordId); if (presentationRecord == null) { return(VCResponseHelpers.Error(IdentityConstants.UnknownPresentationRecordId, "Cannot find respective record id")); } WalletPublicDid acapyPublicDid; try { acapyPublicDid = await _acapyClient.WalletDidPublic(); } catch (Exception e) { _logger.LogError(e, "Cannot fetch ACAPy wallet public did"); return(VCResponseHelpers.Error(IdentityConstants.AcapyCallFailed, "Cannot fetch ACAPy wallet public did")); } PresentationRequestMessage presentationRequest; string presentationRequestId; try { var response = await _acapyClient.CreatePresentationRequestAsync(presentationRecord.Configuration); presentationRequest = BuildPresentationRequest(response, acapyPublicDid); presentationRequestId = response.PresentationExchangeId; } catch (Exception e) { _logger.LogError(e, "Failed to create presentation request"); return(VCResponseHelpers.Error(IdentityConstants.AcapyCallFailed, "Failed to create presentation request")); } // create a full and short url versions of a presentation requests string shortUrl; try { var url = string.Format("{0}?m={1}", _options.PublicOrigin, presentationRequest.ToJson().ToBase64()); shortUrl = await _urlShortenerService.CreateShortUrlAsync(url); } catch (Exception e) { _logger.LogError(e, "Presentation url build failed"); return(VCResponseHelpers.Error(IdentityConstants.PresentationUrlBuildFailed, "Presentation url build failed")); } // persist presentation request details in session try { var session = await _sessionStorage.CreateSessionAsync(new AuthSession() { PresentationRequestId = presentationRequestId, PresentationRecordId = presentationRecordId, PresentationRequest = presentationRequest.Request.ExtractIndyPresentationRequest().ToJson(), RequestParameters = values.AllKeys.ToDictionary(t => t, t => values[t]) }); // set up a session cookie context.Response.Cookies.Append(IdentityConstants.SessionIdCookieName, session.Id); } catch (Exception e) { _logger.LogError(e, "Failed to start a new session"); return(VCResponseHelpers.Error(IdentityConstants.SessionStartFailed, "Failed to start a new session")); } return(new AuthorizationEndpointResult( new AuthorizationViewModel( shortUrl, $"{_options.PublicOrigin}/{IdentityConstants.ChallengePollUri}?{IdentityConstants.ChallengeIdQueryParameterName}={presentationRequestId}", $"{_options.PublicOrigin}/{IdentityConstants.AuthorizeCallbackUri}?{IdentityConstants.ChallengeIdQueryParameterName}={presentationRequestId}", presentationRequest.ToJson() ))); }
public async Task <IEndpointResult> ProcessAsync(HttpContext context) { _logger.LogDebug($"Starting token request"); NameValueCollection values; if (HttpMethods.IsPost(context.Request.Method)) { if (!context.Request.HasFormContentType) { _logger.LogDebug($"Unsupported media type"); return(new StatusCodeResult(HttpStatusCode.UnsupportedMediaType)); } values = context.Request.Form.AsNameValueCollection(); } else { _logger.LogDebug($"Method not allowed"); return(new StatusCodeResult(HttpStatusCode.MethodNotAllowed)); } var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { _logger.LogDebug($"Invalid client"); return(VCResponseHelpers.Error(OidcConstants.TokenErrors.InvalidClient)); } var grantType = values.Get(IdentityConstants.GrantTypeParameterName); if (string.IsNullOrEmpty(grantType)) { _logger.LogDebug($"Invalid grant type of : {grantType}"); return(VCResponseHelpers.Error(IdentityConstants.InvalidGrantTypeError)); } var sessionId = values.Get(IdentityConstants.AuthorizationCodeParameterName); if (string.IsNullOrEmpty(sessionId)) { _logger.LogDebug($"Invalid authorization code : {sessionId}"); return(VCResponseHelpers.Error(IdentityConstants.InvalidAuthorizationCodeError)); } var session = await _sessionStore.FindBySessionIdAsync(sessionId); if (session == null) { _logger.LogDebug($"Invalid session : {sessionId}"); return(VCResponseHelpers.Error(IdentityConstants.InvalidSessionError, $"Cannot find stored session")); } if (session.PresentationRequestSatisfied == false) { _logger.LogDebug($"Presentation not satisfied, session id : {sessionId}"); return(VCResponseHelpers.Error(IdentityConstants.InvalidSessionError, "Presentation request wasn't satisfied")); } try { _logger.LogDebug($"Constructing token result for session : {sessionId}"); return(new TokenEndpointResult(session, _clientValidator, _tokenIssuerService, _presentationConfigurationService, _sessionStore, _logger)); } catch (Exception e) { _logger.LogError(e, "Failed to create a token response"); return(VCResponseHelpers.Error(IdentityConstants.GeneralError, "Failed to create a token")); } }