/// <summary> /// Initializes a new instance of the <see cref="OidcClient"/> class. /// </summary> /// <param name="options">The options.</param> public OidcClient(OidcClientOptions options) { _authorizeClient = new AuthorizeClient(options); _validator = new ResponseValidator(options); _options = options; }
public ResponseProcessor(OidcClientOptions options, Func <CancellationToken, Task> refreshKeysAsync) { _options = options; _refreshKeysAsync = refreshKeysAsync; _logger = options.LoggerFactory.CreateLogger <ResponseProcessor>(); _crypto = new CryptoHelper(options); }
public ResponseProcessor(OidcClientOptions options, Func <Task> refreshKeysAsync) { _options = options; _refreshKeysAsync = refreshKeysAsync; _logger = options.LoggerFactory.CreateLogger <ResponseProcessor>(); _tokenValidator = new IdentityTokenValidator(options, refreshKeysAsync); _crypto = new CryptoHelper(options); }
/// <summary> /// Initializes a new instance of the <see cref="OidcClient"/> class. /// </summary> /// <param name="options">The options.</param> /// <exception cref="System.ArgumentNullException">options</exception> public OidcClient(OidcClientOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); if (options.ProviderInformation == null) { if (options.Authority.IsMissing()) throw new ArgumentException("No authority specified", nameof(_options.Authority)); useDiscovery = true; } _options = options; _logger = options.LoggerFactory.CreateLogger<OidcClient>(); _authorizeClient = new AuthorizeClient(options); _processor = new ResponseProcessor(options, EnsureProviderInformationAsync); }
/// <inheritdoc /> #pragma warning disable 1998 public async Task <IdentityTokenValidationResult> ValidateAsync(string identityToken, OidcClientOptions options, CancellationToken cancellationToken = default) #pragma warning restore 1998 { var logger = options.LoggerFactory.CreateLogger <JwtHandlerIdentityTokenValidator>(); logger.LogTrace("Validate"); // setup general validation parameters var parameters = new TokenValidationParameters { ValidIssuer = options.ProviderInformation.IssuerName, ValidAudience = options.ClientId, ValidateIssuer = options.Policy.ValidateTokenIssuerName, NameClaimType = JwtClaimTypes.Name, RoleClaimType = JwtClaimTypes.Role, ClockSkew = options.ClockSkew }; // read the token signing algorithm var handler = new JsonWebTokenHandler(); JsonWebToken jwt; try { jwt = handler.ReadJsonWebToken(identityToken); } catch (Exception ex) { return(new IdentityTokenValidationResult { Error = $"Error validating identity token: {ex.ToString()}" }); } var algorithm = jwt.Alg; // if token is unsigned, and this is allowed, skip signature validation if (string.Equals(algorithm, "none", StringComparison.OrdinalIgnoreCase)) { if (options.Policy.RequireIdentityTokenSignature) { return(new IdentityTokenValidationResult { Error = $"Identity token is not signed. Signatures are required by policy" }); } else { logger.LogInformation("Identity token is not signed. This is allowed by configuration."); parameters.RequireSignedTokens = false; } } else { // check if signature algorithm is allowed by policy if (!options.Policy.ValidSignatureAlgorithms.Contains(algorithm)) { return(new IdentityTokenValidationResult { Error = $"Identity token uses invalid algorithm: {algorithm}" }); } ; } var result = ValidateSignature(identityToken, handler, parameters, options, logger); if (result.IsValid == false) { if (result.Exception is SecurityTokenSignatureKeyNotFoundException) { logger.LogWarning("Key for validating token signature cannot be found. Refreshing keyset."); return(new IdentityTokenValidationResult { Error = "invalid_signature" }); } if (result.Exception is SecurityTokenUnableToValidateException) { return(new IdentityTokenValidationResult { Error = "unable_to_validate_token" }); } throw result.Exception; } var user = new ClaimsPrincipal(result.ClaimsIdentity); var error = CheckRequiredClaim(user); if (error.IsPresent()) { return(new IdentityTokenValidationResult { Error = error }); } return(new IdentityTokenValidationResult { User = user, SignatureAlgorithm = algorithm }); }
private TokenValidationResult ValidateSignature(string identityToken, JsonWebTokenHandler handler, TokenValidationParameters parameters, OidcClientOptions options, ILogger logger) { if (parameters.RequireSignedTokens) { // read keys from provider information var keys = new List <SecurityKey>(); foreach (var webKey in options.ProviderInformation.KeySet.Keys) { if (webKey.E.IsPresent() && webKey.N.IsPresent()) { // only add keys used for signatures if (webKey.Use == "sig" || webKey.Use == null) { var e = Base64Url.Decode(webKey.E); var n = Base64Url.Decode(webKey.N); var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n }); key.KeyId = webKey.Kid; keys.Add(key); logger.LogDebug("Added signing key with kid: {kid}", key?.KeyId ?? "not set"); } } else if (webKey.X.IsPresent() && webKey.Y.IsPresent() && webKey.Crv.IsPresent()) { var ec = ECDsa.Create(new ECParameters { Curve = GetCurveFromCrvValue(webKey.Crv), Q = new ECPoint { X = Base64Url.Decode(webKey.X), Y = Base64Url.Decode(webKey.Y) } }); var key = new ECDsaSecurityKey(ec); key.KeyId = webKey.Kid; keys.Add(key); } else { logger.LogDebug("Signing key with kid: {kid} currently not supported", webKey.Kid ?? "not set"); } } parameters.IssuerSigningKeys = keys; } return(handler.ValidateToken(identityToken, parameters)); }
/// <summary> /// Initializes a new instance of the <see cref="AuthorizeClient"/> class. /// </summary> /// <param name="options">The options.</param> public AuthorizeClient(OidcClientOptions options) { _options = options; _logger = options.LoggerFactory.CreateLogger <AuthorizeClient>(); _crypto = new CryptoHelper(options); }
public CryptoHelper(OidcClientOptions options) { _options = options; _logger = options.LoggerFactory.CreateLogger <CryptoHelper>(); }
/// <inheritdoc /> public Task <IdentityTokenValidationResult> ValidateAsync(string identityToken, OidcClientOptions options, CancellationToken cancellationToken = default) { var parts = identityToken.Split('.'); if (parts.Length != 3) { var error = new IdentityTokenValidationResult { Error = "invalid_jwt" }; return(Task.FromResult(error)); } var payload = Encoding.UTF8.GetString((Base64Url.Decode(parts[1]))); var values = JsonSerializer.Deserialize <Dictionary <string, JsonElement> >(payload); var claims = new List <Claim>(); foreach (var element in values) { if (element.Value.ValueKind == JsonValueKind.Array) { foreach (var item in element.Value.EnumerateArray()) { claims.Add(new Claim(element.Key, item.ToString())); } } else { claims.Add(new Claim(element.Key, element.Value.ToString())); } } var result = new IdentityTokenValidationResult { SignatureAlgorithm = "none", User = new ClaimsPrincipal(new ClaimsIdentity(claims, "none", "name", "role")) }; return(Task.FromResult(result)); }
public IdentityTokenValidator(OidcClientOptions options, Func <Task> refreshKeysAsync) { _options = options; _logger = options.LoggerFactory.CreateLogger <IdentityTokenValidator>(); _refreshKeysAsync = refreshKeysAsync; }
public OidcClient(OidcClientOptions options) { _authorizeClient = new AuthorizeClient(options); _options = options; }
/// <summary> /// Initializes a new instance of the <see cref="AuthorizeClient"/> class. /// </summary> /// <param name="options">The options.</param> public AuthorizeClient(OidcClientOptions options) { _options = options; }
public ResponseValidator(OidcClientOptions options) { _options = options; }