예제 #1
0
        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()
                           )));
        }