// todo ///// <summary> ///// Initializes a new instance of the <see cref="DefaultTokenService" /> class. ///// </summary> ///// <param name="options">The options.</param> ///// <param name="claimsProvider">The claims provider.</param> ///// <param name="tokenHandles">The token handles.</param> ///// <param name="signingService">The signing service.</param> ///// <param name="events">The OWIN environment service.</param> ///// <param name="owinEnvironmentService">The events service.</param> //public DefaultTokenService(IdentityServerOptions options, IClaimsProvider claimsProvider, ITokenHandleStore tokenHandles, ITokenSigningService signingService, IEventService events, OwinEnvironmentService owinEnvironmentService) //{ // _options = options; // _claimsProvider = claimsProvider; // _tokenHandles = tokenHandles; // _signingService = signingService; // _events = events; // _owinEnvironmentService = owinEnvironmentService; //} /// <summary> /// Creates an identity token. /// </summary> /// <param name="request">The token creation request.</param> /// <returns> /// An identity token /// </returns> public virtual async Task <Token> CreateIdentityTokenAsync(TokenCreationRequest request) { _logger.LogVerbose("Creating identity token"); request.Validate(); // host provided claims var claims = new List <Claim>(); // if nonce was sent, must be mirrored in id token if (request.Nonce.IsPresent()) { claims.Add(new Claim(Constants.ClaimTypes.Nonce, request.Nonce)); } // add iat claim claims.Add(new Claim(Constants.ClaimTypes.IssuedAt, DateTimeOffsetHelper.UtcNow.ToEpochTime().ToString(), ClaimValueTypes.Integer)); // add at_hash claim if (request.AccessTokenToHash.IsPresent()) { claims.Add(new Claim(Constants.ClaimTypes.AccessTokenHash, HashAdditionalData(request.AccessTokenToHash))); } // add c_hash claim if (request.AuthorizationCodeToHash.IsPresent()) { claims.Add(new Claim(Constants.ClaimTypes.AuthorizationCodeHash, HashAdditionalData(request.AuthorizationCodeToHash))); } // add sid if present if (request.ValidatedRequest.SessionId.IsPresent()) { claims.Add(new Claim(Constants.ClaimTypes.SessionId, request.ValidatedRequest.SessionId)); } claims.AddRange(await _claimsProvider.GetIdentityTokenClaimsAsync( request.Subject, request.Client, request.Scopes, request.IncludeAllIdentityClaims, request.ValidatedRequest)); var issuer = _context.GetIssuerUri(); var token = new Token(Constants.TokenTypes.IdentityToken) { Audience = request.Client.ClientId, Issuer = issuer, Lifetime = request.Client.IdentityTokenLifetime, Claims = claims.Distinct(new ClaimComparer()).ToList(), Client = request.Client }; return(token); }
private async Task <IEndpointResult> ExecuteDiscoDocAsync(HttpContext context) { _logger.LogTrace("Start discovery request"); var baseUrl = _context.GetIdentityServerBaseUrl().EnsureTrailingSlash(); var allScopes = await _scopes.GetScopesAsync(publicOnly : true); var showScopes = new List <Scope>(); var document = new DiscoveryDocument { issuer = _context.GetIssuerUri(), subject_types_supported = new[] { "public" }, id_token_signing_alg_values_supported = new[] { Constants.SigningAlgorithms.RSA_SHA_256 } }; // scopes if (_options.DiscoveryOptions.ShowIdentityScopes) { showScopes.AddRange(allScopes.Where(s => s.Type == ScopeType.Identity)); } if (_options.DiscoveryOptions.ShowResourceScopes) { showScopes.AddRange(allScopes.Where(s => s.Type == ScopeType.Resource)); } if (showScopes.Any()) { document.scopes_supported = showScopes.Where(s => s.ShowInDiscoveryDocument).Select(s => s.Name).ToArray(); } // claims if (_options.DiscoveryOptions.ShowClaims) { var claims = new List <string>(); foreach (var s in allScopes) { claims.AddRange(from c in s.Claims where s.Type == ScopeType.Identity select c.Name); } document.claims_supported = claims.Distinct().ToArray(); } // grant types if (_options.DiscoveryOptions.ShowGrantTypes) { var standardGrantTypes = Constants.SupportedGrantTypes.AsEnumerable(); if (this._options.AuthenticationOptions.EnableLocalLogin == false) { standardGrantTypes = standardGrantTypes.Where(type => type != OidcConstants.GrantTypes.Password); } var showGrantTypes = new List <string>(standardGrantTypes); if (_options.DiscoveryOptions.ShowCustomGrantTypes) { showGrantTypes.AddRange(_customGrants.GetAvailableGrantTypes()); } document.grant_types_supported = showGrantTypes.ToArray(); } // response types if (_options.DiscoveryOptions.ShowResponseTypes) { document.response_types_supported = Constants.SupportedResponseTypes.ToArray(); } // response modes if (_options.DiscoveryOptions.ShowResponseModes) { document.response_modes_supported = Constants.SupportedResponseModes.ToArray(); } // token endpoint authentication methods if (_options.DiscoveryOptions.ShowTokenEndpointAuthenticationMethods) { document.token_endpoint_auth_methods_supported = _parsers.GetAvailableAuthenticationMethods().ToArray(); } // endpoints if (_options.DiscoveryOptions.ShowEndpoints) { if (_options.Endpoints.EnableEndSessionEndpoint) { document.http_logout_supported = true; } if (_options.Endpoints.EnableAuthorizeEndpoint) { document.authorization_endpoint = baseUrl + Constants.RoutePaths.Oidc.Authorize; } if (_options.Endpoints.EnableTokenEndpoint) { document.token_endpoint = baseUrl + Constants.RoutePaths.Oidc.Token; } if (_options.Endpoints.EnableUserInfoEndpoint) { document.userinfo_endpoint = baseUrl + Constants.RoutePaths.Oidc.UserInfo; } if (_options.Endpoints.EnableEndSessionEndpoint) { document.end_session_endpoint = baseUrl + Constants.RoutePaths.Oidc.EndSession; } if (_options.Endpoints.EnableCheckSessionEndpoint) { document.check_session_iframe = baseUrl + Constants.RoutePaths.Oidc.CheckSession; } if (_options.Endpoints.EnableTokenRevocationEndpoint) { document.revocation_endpoint = baseUrl + Constants.RoutePaths.Oidc.Revocation; } if (_options.Endpoints.EnableIntrospectionEndpoint) { document.introspection_endpoint = baseUrl + Constants.RoutePaths.Oidc.Introspection; } } if (_options.DiscoveryOptions.ShowKeySet) { if (_options.SigningCertificate != null) { document.jwks_uri = baseUrl + Constants.RoutePaths.Oidc.DiscoveryWebKeys; } } return(new DiscoveryDocumentResult(document, _options.DiscoveryOptions.CustomEntries)); }
public virtual async Task <TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null) { _logger.LogVerbose("Start access token validation"); _log.ExpectedScope = expectedScope; _log.ValidateLifetime = true; TokenValidationResult result; if (token.Contains(".")) { if (token.Length > _options.InputLengthRestrictions.Jwt) { _logger.LogError("JWT too long"); return(new TokenValidationResult { IsError = true, Error = Constants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Jwt.ToString(); result = await ValidateJwtAsync( token, string.Format(Constants.AccessTokenAudience, _context.GetIssuerUri().EnsureTrailingSlash()), await _keyService.GetValidationKeysAsync()); } else { if (token.Length > _options.InputLengthRestrictions.TokenHandle) { _logger.LogError("token handle too long"); return(new TokenValidationResult { IsError = true, Error = Constants.ProtectedResourceErrors.InvalidToken, ErrorDescription = "Token too long" }); } _log.AccessTokenType = AccessTokenType.Reference.ToString(); result = await ValidateReferenceAccessTokenAsync(token); } _log.Claims = result.Claims.ToClaimsDictionary(); if (result.IsError) { return(result); } if (expectedScope.IsPresent()) { var scope = result.Claims.FirstOrDefault(c => c.Type == Constants.ClaimTypes.Scope && c.Value == expectedScope); if (scope == null) { LogError(string.Format("Checking for expected scope {0} failed", expectedScope)); return(Invalid(Constants.ProtectedResourceErrors.InsufficientScope)); } } var customResult = await _customValidator.ValidateAccessTokenAsync(result); if (customResult.IsError) { LogError("Custom validator failed: " + (customResult.Error ?? "unknown")); return(customResult); } // add claims again after custom validation _log.Claims = customResult.Claims.ToClaimsDictionary(); LogSuccess(); return(customResult); }