public async Task <string> IssueJwtAsync(int lifetime, string issuer, string presentationRecordId, PartialPresentation presentation)
        {
            var claims = new List <Claim>
            {
                new Claim(IdentityConstants.PresentationRequestConfigIDParamName, presentationRecordId),
                new Claim("amr", IdentityConstants.VCAuthnScopeName)
            };

            var presentationConfig = await _presentationConfigurationService.GetAsync(presentationRecordId);

            foreach (var attr in presentation.RequestedProof.RevealedAttributes)
            {
                claims.Add(new Claim(attr.Key, attr.Value.Raw));
                if (string.Equals(attr.Key, presentationConfig.SubjectIdentifier, StringComparison.InvariantCultureIgnoreCase))
                {
                    claims.Add(new Claim("sub", attr.Value.Raw));
                }
            }

            var token = new Token
            {
                CreationTime = _clock.UtcNow.UtcDateTime,
                Issuer       = issuer,
                Lifetime     = lifetime,
                Claims       = new HashSet <Claim>(claims, new ClaimComparer())
            };

            return(await _tokenCreation.CreateTokenAsync(token));
        }
            private async Task <List <Claim> > GetClaims()
            {
                _logger.LogDebug($"Creating Claims list for presentation record id : {_session.PresentationRecordId}");

                var claims = new List <Claim>
                {
                    new Claim(IdentityConstants.PresentationRequestConfigIDParamName, _session.PresentationRecordId),
                    new Claim(IdentityConstants.AuthenticationContextReferenceIdentityTokenKey, IdentityConstants.VCAuthnScopeName)
                };

                var presentationConfig = await _presentationConfigurationService.GetAsync(_session.PresentationRecordId);

                if (_session.RequestParameters.ContainsKey(IdentityConstants.NonceParameterName))
                {
                    claims.Add(new Claim(IdentityConstants.NonceParameterName, _session.RequestParameters[IdentityConstants.NonceParameterName]));
                }

                PresentationRequest presentationRequest = JsonConvert.DeserializeObject <PresentationRequest>(_session.PresentationRequest);

                foreach (var requestedAttr in presentationRequest.RequestedAttributes)
                {
                    if (_session.Presentation.RequestedProof.RevealedAttributes.ContainsKey(requestedAttr.Key))
                    {
                        _logger.LogDebug("Processing revealed attributes");
                        claims.Add(new Claim(requestedAttr.Value.Name, _session.Presentation.RequestedProof.RevealedAttributes[requestedAttr.Key].Raw));
                        if (!string.IsNullOrEmpty(presentationConfig.SubjectIdentifier) && string.Equals(requestedAttr.Value.Name, presentationConfig.SubjectIdentifier, StringComparison.InvariantCultureIgnoreCase))
                        {
                            claims.Add(new Claim(IdentityConstants.SubjectIdentityTokenKey, _session.Presentation.RequestedProof.RevealedAttributes[requestedAttr.Key].Raw));
                        }
                    }
                    else if (_session.Presentation.RequestedProof.RevealedAttributesGroups.ContainsKey(requestedAttr.Key))
                    {
                        _logger.LogDebug("Processing revealed attributes groups");
                        foreach (string name in requestedAttr.Value.Names)
                        {
                            claims.Add(new Claim(name, _session.Presentation.RequestedProof.RevealedAttributesGroups[requestedAttr.Key].Values[name].Raw));
                            if (!string.IsNullOrEmpty(presentationConfig.SubjectIdentifier) && string.Equals(name, presentationConfig.SubjectIdentifier, StringComparison.InvariantCultureIgnoreCase))
                            {
                                claims.Add(new Claim(IdentityConstants.SubjectIdentityTokenKey, _session.Presentation.RequestedProof.RevealedAttributesGroups[requestedAttr.Key].Values[name].Raw));
                            }
                        }
                    }
                }

                if (!claims.Any(_ => _.Type == IdentityConstants.SubjectIdentityTokenKey))
                {
                    claims.Add(new Claim(IdentityConstants.SubjectIdentityTokenKey, Guid.NewGuid().ToString()));
                }

                // Add "issued at" standard OIDC claim - see https://tools.ietf.org/html/rfc7519#section-4
                claims.Add(new Claim(IdentityConstants.OIDCTokenIssuedAt, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), System.Security.Claims.ClaimValueTypes.Integer));

                _logger.LogDebug($"Claims list created for presentation record id : {_session.PresentationRecordId}, values : {claims.ToJson()}");

                return(claims);
            }
Beispiel #3
0
        public async Task <ActionResult <PresentationRecord> > GetConfig(string id)
        {
            var record = await _service.GetAsync(id);

            if (record == null)
            {
                return(NotFound());
            }

            return(Ok(record));
        }
Beispiel #4
0
            private async Task <List <Claim> > GetClaims()
            {
                _logger.LogDebug($"Creating Claims list for presentation record id : {_session.PresentationRecordId}");

                var claims = new List <Claim>
                {
                    new Claim(IdentityConstants.PresentationRequestConfigIDParamName, _session.PresentationRecordId),
                    new Claim(IdentityConstants.AuthenticationContextReferenceIdentityTokenKey, IdentityConstants.VCAuthnScopeName)
                };

                var presentationConfig = await _presentationConfigurationService.GetAsync(_session.PresentationRecordId);

                if (_session.RequestParameters.ContainsKey(IdentityConstants.NonceParameterName))
                {
                    claims.Add(new Claim(IdentityConstants.NonceParameterName, _session.RequestParameters[IdentityConstants.NonceParameterName]));
                }

                PresentationRequest presentationRequest = JsonConvert.DeserializeObject <PresentationRequest>(_session.PresentationRequest);

                foreach (var requestedAttr in presentationRequest.RequestedAttributes)
                {
                    if (_session.Presentation.RequestedProof.RevealedAttributes.ContainsKey(requestedAttr.Key))
                    {
                        claims.Add(new Claim(requestedAttr.Value.Name, _session.Presentation.RequestedProof.RevealedAttributes[requestedAttr.Key].Raw));
                        if (!string.IsNullOrEmpty(presentationConfig.SubjectIdentifier) && string.Equals(requestedAttr.Value.Name, presentationConfig.SubjectIdentifier, StringComparison.InvariantCultureIgnoreCase))
                        {
                            claims.Add(new Claim(IdentityConstants.SubjectIdentityTokenKey, _session.Presentation.RequestedProof.RevealedAttributes[requestedAttr.Key].Raw));
                        }
                    }
                }

                if (!claims.Any(_ => _.Type == IdentityConstants.SubjectIdentityTokenKey))
                {
                    claims.Add(new Claim(IdentityConstants.SubjectIdentityTokenKey, Guid.NewGuid().ToString()));
                }

                _logger.LogDebug($"Claims list created for presentation record id : {_session.PresentationRecordId}, values : {claims.ToJson()}");

                return(claims);
            }
Beispiel #5
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()
                           )));
        }