public async Task <ActionResult <DeviceCode> > GetDeviceCodeByUserCodeAsync(string userCode) { // validate client var clientResult = await _clientValidator.ValidateAsync(this.HttpContext); if (clientResult.Client == null) { return(Unauthorized(OidcConstants.TokenErrors.InvalidClient)); } var grantType = clientResult.Client.AllowedGrantTypes.FirstOrDefault(agt => agt == OidcConstants.GrantTypes.DeviceCode); if (grantType == null) { return(Unauthorized(OidcConstants.TokenErrors.InvalidGrant)); } var deviceCode = await _deviceFlowStore.FindByUserCodeAsync(userCode.Sha256()); if (deviceCode == null) { return(NotFound()); } return(deviceCode); }
private async Task <IEndpointResult> ProcessDeviceAuthorizationRequestAsync(HttpContext context) { _logger.LogDebug("Start device authorize request."); // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(Error(OidcConstants.TokenErrors.InvalidClient)); } // validate request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); var requestResult = await _requestValidator.ValidateAsync(form, clientResult); if (requestResult.IsError) { await _events.RaiseAsync(new DeviceAuthorizationFailureEvent(requestResult)); return(Error(requestResult.Error, requestResult.ErrorDescription)); } var baseUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash(); // create response _logger.LogTrace("Calling into device authorize response generator: {type}", _responseGenerator.GetType().FullName); var response = await _responseGenerator.ProcessAsync(requestResult, baseUrl); await _events.RaiseAsync(new DeviceAuthorizationSuccessEvent(response, requestResult)); // return result _logger.LogDebug("Device authorize request success."); return(new DeviceAuthorizationResult(response)); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { // var audienceName = context.Request.Raw.Get("audience"); // var audience = await _resourceStore.FindApiResourceAsync(audienceName); var userToken = context.Request.Raw.Get("subject_token"); if (string.IsNullOrEmpty(userToken)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return; } var clientValidationResult = await _clientValidator.ValidateAsync(_context.HttpContext); var result = await _validator.ValidateAccessTokenAsync(userToken); if (result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); return; } // // get user's identity var sub = result.Claims.FirstOrDefault(c => c.Type == "sub")?.Value; context.Result = new GrantValidationResult(sub, GrantType, new [] { new Claim("act", JsonConvert.SerializeObject(new { sub = clientValidationResult.Client.ClientId }), IdentityServerConstants.ClaimValueTypes.Json) }); return; }
private async Task <IEndpointResult> ProcessTokenRequestAsync(HttpContext context) { // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(Error(OidcConstants.TokenErrors.InvalidClient)); } // validate request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult); if (requestResult.IsError) { await _events.RaiseAsync(new TokenIssuedFailureEvent(requestResult)); return(Error(requestResult.Error, requestResult.ErrorDescription, requestResult.CustomResponse)); } // create response var response = await _responseGenerator.ProcessAsync(requestResult); await _events.RaiseAsync(new TokenIssuedSuccessEvent(response, requestResult)); // return result return(new TokenResult(response)); }
public async Task <ClientSecretValidationResult> ValidateAsync(HttpContext context) { _logger.LogDebug("Start InternalServiceClient Validation"); var body = await context.Request.ReadFormAsync(); if (body != null) { if (!validateClient(body)) { return(new ClientSecretValidationResult { Error = "invalid_client", ErrorDescription = "This endpoint is only allowed for service clients" }); } else { // Check if the client exists and enabled in the database var clientResult = await _clientValidator.ValidateAsync(context); // Whatever is the result error or success, pass it back return(clientResult); } } _logger.LogDebug("Completed InternalServiceClient Validation"); return(null); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); if (context == null) { throw new ArgumentNullException(nameof(context)); } var raw = context.Request.Raw; var validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(validatedRequest) }; await _arbitraryNoSubjectRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); return; } // validate HTTP for clients if (HttpMethods.IsPost(_httpContextAccessor.HttpContext.Request.Method) && _httpContextAccessor.HttpContext.Request.HasFormContentType) { // validate client var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { validatedRequest.SetClient(clientResult.Client); } } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); if (grantType.IsMissing()) { LogError("Grant type is missing"); context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType); return; } if (grantType.Length > _options.InputLengthRestrictions.GrantType) { LogError("Grant type is too long"); context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType); return; } validatedRequest.GrantType = grantType; context.Result = new GrantValidationResult(); }
private async Task <IdpTokenResponse> GetIdpToken(NameValueCollection parameters) { var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (clientResult.IsError) { return(new IdpTokenResponse { Custom = new Dictionary <string, object> { { "Error", "invalid_client" }, { "ErrorDescription", "Invalid client/secret combination" } } }); } var validationResult = await _requestValidator.ValidateRequestAsync(parameters, clientResult); if (validationResult.IsError) { return(new IdpTokenResponse { Custom = new Dictionary <string, object> { { "Error", validationResult.Error }, { "ErrorDescription", validationResult.ErrorDescription } } }); } return(await _responseGenerator.ProcessAsync(validationResult)); }
public override async Task <IEndpointResult> ProcessAsync(HttpContext context) { Logger.LogDebug("Start authorize2 request"); if (!HttpMethods.IsPost(context.Request.Method)) { Logger.LogWarning("Invalid HTTP request for token endpoint"); return(Error(Authorize2Constants.Authorize2Errors.InvalidRequest)); } var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(context); if (tokenUsageResult.TokenFound == false) { var error = "No access token found."; _logger.LogError(error); return(Error(OidcConstants.ProtectedResourceErrors.InvalidToken)); } if (!context.Request.HasFormContentType) { return(new StatusCodeResult(HttpStatusCode.UnsupportedMediaType)); } // validate the request Logger.LogTrace("Calling into userinfo request validator: {type}", _requestValidator.GetType().FullName); var validationResult = await _requestValidator.ValidateRequestAsync(tokenUsageResult.Token); if (validationResult.IsError) { //_logger.LogError("Error validating validationResult.Error); return(Error(validationResult.Error)); } // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(Error(Authorize2Constants.Authorize2Errors.InvalidClient)); } // validate request NameValueCollection values = (await context.Request.ReadFormAsync()).AsNameValueCollection(); Logger.LogTrace("Calling into token request validator: {type}", _validator2.GetType().FullName); var requestResult = await _validator2.ValidateRequestAsync(values, clientResult); // var user = await UserSession.GetUserAsync(); var user = validationResult.Subject; var result = await ProcessAuthorizeRequestAsync(values, user, null); Logger.LogTrace("End authorize request. result type: {0}", result?.GetType().ToString() ?? "-none-"); // return Error(Authorize2Constants.Authorize2Errors.InvalidClient); return(new Authorize2Result(result as AuthorizeResult)); }
public async Task Invoke(HttpContext httpContext, IScopedStorage scopedStorage) { if (!string.IsNullOrEmpty(PathRootUrl)) { FixUpPath(httpContext); } // start tracking await FetchDiscoveryData(httpContext); var endpointKey = (from item in _endpointDictionary where item.Value == httpContext.Request.Path.Value select item.Key).FirstOrDefault(); if (endpointKey == null) { // not for us await _next(httpContext); return; } _logger.LogInformation($"endpointKey={endpointKey},path={httpContext.Request.Path}"); var requestRecord = new IdentityServerRequestRecord { HttpContext = httpContext, EndpointKey = endpointKey }; // validate HTTP for clients if (HttpMethods.IsPost(httpContext.Request.Method) && httpContext.Request.HasFormContentType) { // validate client var clientResult = await _clientValidator.ValidateAsync(httpContext); if (!clientResult.IsError) { requestRecord.Client = clientResult.Client; } } foreach (var evaluator in _evaluators) { var directive = await ProcessPreEvaluatorAsync(evaluator, requestRecord); if (directive == RequestTrackerEvaluatorDirective.DenyRequest) { return; // do not continue to the real IdentityServer4 middleware. } } scopedStorage.Storage["IdentityServerRequestRecord"] = requestRecord; // // The following invoke is letting the request continue on into the pipeline // await _next(httpContext); }
private async Task <IEndpointResult> ProcessTokenRequestAsync(HttpContext context) { _logger.LogDebug("Start token request."); // validate request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); var userName = form.Get(OidcConstants.TokenRequest.UserName); var password = form.Get(OidcConstants.TokenRequest.Password); var scope = form.Get(OidcConstants.TokenRequest.Scope); if (scope == "phone_number") { var getUserByPhoneNumber = await _usersService.GetByPhoneNumberOTP(userName, password); if (getUserByPhoneNumber != null) { form.Remove("username"); form.Remove("password"); form.Remove("scope"); form.Add("username", getUserByPhoneNumber.Username); form.Add("password", getUserByPhoneNumber.Password); scope = null; //form.Add("scope", "openid"); } } // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(Error(OidcConstants.TokenErrors.InvalidClient)); } // validate request //var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); _logger.LogTrace("Calling into token request validator: {type}", _requestValidator.GetType().FullName); var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult); if (requestResult.IsError) { await _events.RaiseAsync(new TokenIssuedFailureEvent(requestResult)); return(Error(requestResult.Error, requestResult.ErrorDescription, requestResult.CustomResponse)); } // create response _logger.LogTrace("Calling into token request response generator: {type}", _responseGenerator.GetType().FullName); var response = await _responseGenerator.ProcessAsync(requestResult); await _events.RaiseAsync(new TokenIssuedSuccessEvent(response, requestResult)); LogTokens(response, requestResult); // return result _logger.LogDebug("Token request success."); return(new TokenResult(response)); }
private async Task <IEndpointResult> ProcessTokenRequestAsync(HttpContext context) { _logger.LogTrace("Start token request."); // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { _logger.LogDebug("Invalid client"); return(Error(OidcConstants.TokenErrors.InvalidClient)); } // validate request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); if (_logger.IsEnabled(LogLevel.Trace)) { _logger.LogTrace("Calling into token request validator: {type}", _requestValidator.GetType().FullName); } var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult); if (requestResult.IsError) { _logger.LogDebug("Token issued failure"); await _events.RaiseAsync(new TokenIssuedFailureEvent(requestResult)); return(Error(requestResult.Error, requestResult.ErrorDescription, requestResult.CustomResponse)); } _logger.LogDebug("Get IP address and device type"); requestResult.ValidatedRequest.ClientIp = context.GetRequestIp(); requestResult.ValidatedRequest.Device = context .GetHeaderValueAs <string>("User-Agent") .GetDevice(); // create response if (_logger.IsEnabled(LogLevel.Trace)) { _logger.LogTrace("Calling into token request response generator: {type}", _responseGenerator.GetType().FullName); } var response = await _responseGenerator.ProcessAsync(requestResult); _logger.LogTrace("Raise token issued successfully event"); await _events.RaiseAsync(new TokenIssuedSuccessEvent(response, requestResult)); LogTokens(response, requestResult); // return result _logger.LogDebug("Token request success."); return(new TokenResult(response)); }
private async Task <IEndpointResult> ProcessRevocationRequestAsync(HttpContext context) { _logger.LogDebug("Start revocation request."); // validate client var clientValidationResult = await _clientValidator.ValidateAsync(context); if (clientValidationResult.IsError) { return(new TokenRevocationErrorResult(OidcConstants.TokenErrors.InvalidClient)); } _logger.LogTrace("Client validation successful"); // validate the token request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); _logger.LogTrace("Calling into token revocation request validator: {type}", _requestValidator.GetType().FullName); var requestValidationResult = await _requestValidator.ValidateRequestAsync(form, clientValidationResult.Client); if (requestValidationResult.IsError) { return(new TokenRevocationErrorResult(requestValidationResult.Error)); } _logger.LogTrace("Calling into token revocation response generator: {type}", _responseGenerator.GetType().FullName); var response = await _responseGenerator.ProcessAsync(requestValidationResult); if (response.Success) { _logger.LogInformation("Token revocation complete"); await _events.RaiseAsync(new TokenRevokedSuccessEvent(requestValidationResult, requestValidationResult.Client)); } else { _logger.LogInformation("No matching token found"); } if (response.Error.IsPresent()) { return(new TokenRevocationErrorResult(response.Error)); } return(new StatusCodeResult(HttpStatusCode.OK)); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); if (context == null) { throw new ArgumentNullException(nameof(context)); } var raw = context.Request.Raw; _validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(_validatedRequest) }; await _arbitraryNoSubjectRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); return; } var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { _validatedRequest.SetClient(clientResult.Client); } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); _validatedRequest.GrantType = grantType; context.Result = new GrantValidationResult(); }
public async Task ExecuteAsync(HttpContext context) { _logger.LogDebug("Constructing token result"); var issuer = context.GetIdentityServerIssuerUri(); var audience = _session.RequestParameters.ContainsKey(IdentityConstants.ClientId) ? _session.RequestParameters[IdentityConstants.ClientId] : ""; _logger.LogDebug($"Generating token for audience : {audience}"); var token = await _tokenIssuerService.IssueJwtAsync(10000, issuer, new string[] { audience }, await GetClaims()); _logger.LogDebug($"Token created, invalidating session"); if (_sessionStorage.DeleteSession(_session) == false) { _logger.LogError("Failed to delete a session"); } _logger.LogDebug($"Returning token result"); var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client.AllowedCorsOrigins.Count() == 1) { _logger.LogDebug("Adding Access-Control-Allow-Origin header"); context.Response.Headers.Add("Access-Control-Allow-Origin", clientResult.Client.AllowedCorsOrigins.ToArray()); } else { _logger.LogError("Multiple Access-Control-Allow-Origin headers defined"); } await context.Response.WriteJsonAsync(new { access_token = "invalid", id_token = token, token_type = "Bearer" }); }
private async Task <IEndpointResult> ProcessTokenRequestAsync(HttpContext context) { _logger.LogDebug("Start token request."); // validate client var clientResult = await _clientValidator.ValidateAsync(context); if (clientResult.Client == null) { return(Error(OidcConstants.TokenErrors.InvalidClient)); } // validate request var form = (await context.Request.ReadFormAsync()).AsNameValueCollection(); _logger.LogTrace("Calling into token request validator: {type}", _requestValidator.GetType().FullName); var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult); if (requestResult.IsError) { await _events.RaiseAsync(new TokenIssuedFailureEvent(requestResult)); return(Error(requestResult.Error, requestResult.ErrorDescription, requestResult.CustomResponse)); } // create response _logger.LogTrace("Calling into token request response generator: {type}", _responseGenerator.GetType().FullName); var response = await _responseGenerator.ProcessAsync(requestResult); await _events.RaiseAsync(new TokenIssuedSuccessEvent(response, requestResult)); LogTokens(response, requestResult); // return result _logger.LogDebug("Token request success."); return(new TokenResult(response)); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); if (context == null) { throw new ArgumentNullException(nameof(context)); } var raw = context.Request.Raw; _validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(_validatedRequest) }; await _arbitraryResourceOwnerRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); return; } var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { _validatedRequest.SetClient(clientResult.Client); } ///////////////////////////////////////////// // get the grant type // NOTE: The identityserver4 pipeline before us validated to obvious stuff ///////////////////////////////////////////// var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); _validatedRequest.GrantType = grantType; var subject = ""; if (string.IsNullOrWhiteSpace(subject)) { subject = context.Request.Raw.Get("subject"); } // get user's identity var claims = new List <Claim> { new Claim(ClaimTypes.NameIdentifier, subject), new Claim("sub", subject) }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims)); _principalAugmenter.AugmentPrincipal(principal); // optional stuff; var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime); if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride)) { int accessTokenLifetime = 0; bool error = true; if (Int32.TryParse(accessTokenLifetimeOverride, out accessTokenLifetime)) { if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime) { context.Request.AccessTokenLifetime = accessTokenLifetime; error = false; } } if (error) { var errorDescription = $"{Constants.AccessTokenLifetime} out of range. Must be > 0 and <= configured AccessTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); return; } } context.Result = new GrantValidationResult(principal.GetSubjectId(), ArbitraryResourceOwnerExtensionGrant.Constants.ArbitraryResourceOwner); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); if (context == null) { throw new ArgumentNullException(nameof(context)); } var contextClient = (context.Request.Client as ClientExtra).ShallowCopy(); context.Request.Client = contextClient; var raw = context.Request.Raw; _validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(_validatedRequest) }; await _arbitraryIdentityRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); return; } // validate HTTP for clients if (HttpMethods.IsPost(_httpContextAccessor.HttpContext.Request.Method) && _httpContextAccessor.HttpContext.Request.HasFormContentType) { // validate client var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { _validatedRequest.SetClient(clientResult.Client); } } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); if (grantType.IsMissing()) { LogError("Grant type is missing"); context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType); return; } if (grantType.Length > _options.InputLengthRestrictions.GrantType) { LogError("Grant type is too long"); context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType); return; } _validatedRequest.GrantType = grantType; var resource = await _resourceStore.GetAllResourcesAsync(); var subject = ""; Claim originAuthTimeClaim = null; // if access_token exists, it wins. var accessToken = context.Request.Raw.Get("access_token"); if (!string.IsNullOrWhiteSpace(accessToken)) { var validateAccessToken = await _tokenValidator.ValidateAccessTokenAsync(accessToken); var queryClaims = from item in validateAccessToken.Claims where item.Type == JwtClaimTypes.Subject select item.Value; subject = queryClaims.FirstOrDefault(); originAuthTimeClaim = (from item in validateAccessToken.Claims where item.Type == $"origin_{JwtClaimTypes.AuthenticationTime}" select item).FirstOrDefault(); if (originAuthTimeClaim == null) { var authTimeClaim = (from item in validateAccessToken.Claims where item.Type == JwtClaimTypes.AuthenticationTime select item).FirstOrDefault(); originAuthTimeClaim = new Claim($"origin_{JwtClaimTypes.AuthenticationTime}", authTimeClaim.Value); } } if (string.IsNullOrWhiteSpace(subject)) { subject = context.Request.Raw.Get("subject"); } // get user's identity var claims = new List <Claim> { new Claim(ClaimTypes.NameIdentifier, subject), new Claim("sub", subject) }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims)); _principalAugmenter.AugmentPrincipal(principal); var userClaimsFinal = new List <Claim>(); // optional stuff; var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime); if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride)) { var accessTokenLifetime = Int32.Parse(accessTokenLifetimeOverride); if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime) { context.Request.AccessTokenLifetime = accessTokenLifetime; } else { var errorDescription = $"{Constants.AccessTokenLifetime} out of range. Must be > 0 and <= configured AccessTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); return; } } // optional stuff; var idTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.IdTokenLifetime); if (!string.IsNullOrWhiteSpace(idTokenLifetimeOverride)) { var idTokenLifetime = Int32.Parse(idTokenLifetimeOverride); if (idTokenLifetime > 0 && idTokenLifetime <= context.Request.Client.IdentityTokenLifetime) { context.Request.Client.IdentityTokenLifetime = idTokenLifetime; } else { var errorDescription = $"{Constants.IdTokenLifetime} out of range. Must be > 0 and <= configured IdentityTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); return; } } //userClaimsFinal.Add(new Claim(ProfileServiceManager.Constants.ClaimKey, Constants.ArbitraryIdentityProfileService)); if (originAuthTimeClaim != null) { userClaimsFinal.Add(originAuthTimeClaim); } context.Result = new GrantValidationResult(principal.GetSubjectId(), ArbitraryIdentityExtensionGrant.Constants.ArbitraryIdentity, userClaimsFinal); }
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 ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); if (context == null) { throw new ArgumentNullException(nameof(context)); } var contextClient = (context.Request.Client as ClientExtra).ShallowCopy(); context.Request.Client = contextClient; var raw = context.Request.Raw; _validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(_validatedRequest) }; await _arbitraryIdentityRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); return; } // validate HTTP for clients if (HttpMethods.IsPost(_httpContextAccessor.HttpContext.Request.Method) && _httpContextAccessor.HttpContext.Request.HasFormContentType) { // validate client var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { _validatedRequest.SetClient(clientResult.Client); } } ///////////////////////////////////////////// // check grant type ///////////////////////////////////////////// var grantType = _validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); _validatedRequest.GrantType = grantType; var resource = await _resourceStore.GetAllResourcesAsync(); var subject = ""; if (string.IsNullOrWhiteSpace(subject)) { subject = context.Request.Raw.Get("subject"); } // get user's identity var claims = new List <Claim> { new Claim(ClaimTypes.NameIdentifier, subject), new Claim("sub", subject), new Claim(JwtClaimTypes.IdentityProvider, _arbitraryIdentityExtensionGrantOptions.IdentityProvider) }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims)); _principalAugmenter.AugmentPrincipal(principal); var userClaimsFinal = new List <Claim>(); // optional stuff; var accessTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.AccessTokenLifetime); if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride)) { int accessTokenLifetime = 0; bool error = true; if (Int32.TryParse(accessTokenLifetimeOverride, out accessTokenLifetime)) { if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime) { context.Request.AccessTokenLifetime = accessTokenLifetime; error = false; } } if (error) { var errorDescription = $"{Constants.AccessTokenLifetime} out of range. Must be > 0 and <= configured AccessTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); return; } } // optional stuff; var idTokenLifetimeOverride = _validatedRequest.Raw.Get(Constants.IdTokenLifetime); if (!string.IsNullOrWhiteSpace(idTokenLifetimeOverride)) { int idTokenLifetime = 0; bool error = true; if (Int32.TryParse(idTokenLifetimeOverride, out idTokenLifetime)) { if (idTokenLifetime > 0 && idTokenLifetime <= context.Request.Client.IdentityTokenLifetime) { context.Request.Client.IdentityTokenLifetime = idTokenLifetime; error = false; } } if (error) { var errorDescription = $"{Constants.IdTokenLifetime} out of range. Must be > 0 and <= configured IdentityTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); return; } } context.Result = new GrantValidationResult( principal.GetSubjectId(), ArbitraryIdentityExtensionGrant.Constants.ArbitraryIdentity, userClaimsFinal, _arbitraryIdentityExtensionGrantOptions.IdentityProvider); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { _logger.LogDebug("Start token request validation"); string grantType = null; string clientId = ""; try { if (context == null) { throw new ArgumentNullException(nameof(context)); } var raw = context.Request.Raw; var validatedRequest = new ValidatedTokenRequest { Raw = raw ?? throw new ArgumentNullException(nameof(raw)), Options = _options }; // validate HTTP for clients if (HttpMethods.IsPost(_httpContextAccessor.HttpContext.Request.Method) && _httpContextAccessor.HttpContext.Request.HasFormContentType) { // validate client var clientResult = await _clientValidator.ValidateAsync(_httpContextAccessor.HttpContext); if (!clientResult.IsError) { validatedRequest.SetClient(clientResult.Client); clientId = clientResult.Client.ClientId; } } ///////////////////////////////////////////// // get grant type. This has already been validated by the time it gets here. ///////////////////////////////////////////// grantType = validatedRequest.Raw.Get(OidcConstants.TokenRequest.GrantType); validatedRequest.GrantType = grantType; var customTokenRequestValidationContext = new CustomTokenRequestValidationContext() { Result = new TokenRequestValidationResult(validatedRequest) }; await _arbitraryResourceOwnerRequestValidator.ValidateAsync(customTokenRequestValidationContext); if (customTokenRequestValidationContext.Result.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, customTokenRequestValidationContext.Result.Error); throw new Exception("Invalid Request"); } var subject = ""; if (string.IsNullOrWhiteSpace(subject)) { subject = context.Request.Raw.Get("subject"); } // get user's identity var claims = new List <Claim> { new Claim(ClaimTypes.NameIdentifier, subject), new Claim("sub", subject) }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims)); _principalAugmenter.AugmentPrincipal(principal); // optional stuff; var accessTokenLifetimeOverride = validatedRequest.Raw.Get(Constants.AccessTokenLifetime); if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride)) { var accessTokenLifetime = Int32.Parse(accessTokenLifetimeOverride); if (accessTokenLifetime > 0 && accessTokenLifetime <= context.Request.AccessTokenLifetime) { context.Request.AccessTokenLifetime = accessTokenLifetime; } else { var errorDescription = $"{Constants.AccessTokenLifetime} out of range. Must be > 0 and <= configured AccessTokenLifetime."; LogError(errorDescription); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, errorDescription); throw new Exception(errorDescription); } } context.Result = new GrantValidationResult(principal.GetSubjectId(), ArbitraryResourceOwnerExtensionGrant.Constants.ArbitraryResourceOwner); } catch (Exception e) { } if (context.Result.IsError) { await _events.RaiseAsync(new ExtensionGrantValidationFailureEvent( clientId, grantType, context.Result.Error)); } }
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")); } }