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); }
public async Task <ActionResult <PresentationRecord> > GetConfig(string id) { var record = await _service.GetAsync(id); if (record == null) { return(NotFound()); } return(Ok(record)); }
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); }
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() ))); }