Пример #1
0
        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}]"));
        }
Пример #2
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()
                           )));
        }
Пример #3
0
        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"));
            }
        }