public void OpenIdConnectProtocolValidator_CHash() { PublicOpenIdConnectProtocolValidator protocolValidator = new PublicOpenIdConnectProtocolValidator(); string authorizationCode1 = protocolValidator.GenerateNonce(); string authorizationCode2 = protocolValidator.GenerateNonce(); string chash1 = IdentityUtilities.CreateCHash(authorizationCode1, "SHA256"); string chash2 = IdentityUtilities.CreateCHash(authorizationCode2, "SHA256"); Dictionary <string, string> emptyDictionary = new Dictionary <string, string>(); Dictionary <string, string> mappedDictionary = new Dictionary <string, string>(protocolValidator.HashAlgorithmMap); JwtSecurityToken jwtWithCHash1 = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.CHash, chash1) }, issuer: IdentityUtilities.DefaultIssuer ); JwtSecurityToken jwtWithEmptyCHash = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.CHash, string.Empty) }, issuer: IdentityUtilities.DefaultIssuer, signingCredentials: IdentityUtilities.DefaultAsymmetricSigningCredentials ); JwtSecurityToken jwtWithoutCHash = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.Nonce, chash2) }, issuer: IdentityUtilities.DefaultIssuer ); JwtSecurityToken jwtWithSignatureChash1 = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.CHash, chash1) }, issuer: IdentityUtilities.DefaultIssuer, signingCredentials: IdentityUtilities.DefaultAsymmetricSigningCredentials ); JwtSecurityToken jwtWithSignatureMultipleChashes = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.CHash, chash1), new Claim(JwtRegisteredClaimNames.CHash, chash2) }, issuer: IdentityUtilities.DefaultIssuer, signingCredentials: IdentityUtilities.DefaultAsymmetricSigningCredentials ); OpenIdConnectProtocolValidationContext validationContext = new OpenIdConnectProtocolValidationContext(); validationContext.AuthorizationCode = authorizationCode2; // chash is not a string, but array ValidateCHash(jwt: jwtWithSignatureMultipleChashes, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10304:")); // chash doesn't match ValidateCHash(jwt: jwtWithSignatureChash1, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10304:")); // use algorithm map validationContext.AuthorizationCode = authorizationCode1; ValidateCHash(jwt: jwtWithSignatureChash1, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); // Creation of algorithm failed, need to map. protocolValidator.SetHashAlgorithmMap(emptyDictionary); ValidateCHash(jwt: jwtWithSignatureChash1, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10307:")); protocolValidator.SetHashAlgorithmMap(mappedDictionary); ValidateCHash(jwt: null, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.ArgumentNullException()); ValidateCHash(jwt: jwtWithoutCHash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10308:")); ValidateCHash(jwt: jwtWithEmptyCHash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10304:")); ValidateCHash(jwt: jwtWithCHash1, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10307:")); ValidateCHash(jwt: jwtWithoutCHash, protocolValidator: protocolValidator, validationContext: null, ee: ExpectedException.ArgumentNullException()); // make sure default alg works. validationContext.AuthorizationCode = authorizationCode1; jwtWithCHash1.Header.Remove("alg"); ValidateCHash(jwt: jwtWithCHash1, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); }
public void OpenIdConnectProtocolValidator_Validate() { JwtSecurityToken jwt = new JwtSecurityToken(); OpenIdConnectProtocolValidationContext validationContext = new OpenIdConnectProtocolValidationContext(); OpenIdConnectProtocolValidator protocolValidator = new OpenIdConnectProtocolValidator(); // jwt null Validate(jwt: null, protocolValidator: protocolValidator, validationContext: null, ee: ExpectedException.ArgumentNullException()); // validationContext null Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: null, ee: ExpectedException.ArgumentNullException()); // aud missing Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10309:")); // exp missing jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, IdentityUtilities.DefaultAudience)); Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10309:")); // iat missing jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow).ToString())); Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10309:")); // iss missing jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString())); Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10309:")); // add iis, nonce is not retuired. protocolValidator.RequireNonce = false; jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, IdentityUtilities.DefaultIssuer)); Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); // nonce invalid string validNonce = protocolValidator.GenerateNonce(); // add the valid 'nonce' but set validationContext.Nonce to a different 'nonce'. protocolValidator.RequireNonce = true; jwt.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nonce, validNonce)); validationContext.Nonce = protocolValidator.GenerateNonce(); Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidNonceException), substringExpected: "IDX10301:")); // sub missing, default not required validationContext.Nonce = validNonce; Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); protocolValidator.RequireSub = true; Validate(jwt: jwt, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10309:")); // authorizationCode invalid string validAuthorizationCode = protocolValidator.GenerateNonce(); string validChash = IdentityUtilities.CreateCHash(validAuthorizationCode, "SHA256"); JwtSecurityToken jwtWithSignatureChash = new JwtSecurityToken ( audience: IdentityUtilities.DefaultAudience, claims: new List <Claim> { new Claim(JwtRegisteredClaimNames.CHash, validChash), new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()), new Claim(JwtRegisteredClaimNames.Nonce, validNonce), new Claim(JwtRegisteredClaimNames.Sub, "sub"), }, expires: DateTime.UtcNow + TimeSpan.FromHours(1), issuer: IdentityUtilities.DefaultIssuer, signingCredentials: IdentityUtilities.DefaultAsymmetricSigningCredentials ); Dictionary <string, string> algmap = new Dictionary <string, string>(protocolValidator.HashAlgorithmMap); protocolValidator.HashAlgorithmMap.Clear(); protocolValidator.HashAlgorithmMap.Add(JwtAlgorithms.RSA_SHA256, "SHA256"); validationContext.Nonce = validNonce; validationContext.AuthorizationCode = validNonce; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolInvalidCHashException), substringExpected: "IDX10304:")); // nonce and authorizationCode valid validationContext.AuthorizationCode = validAuthorizationCode; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); // validate optional claims protocolValidator.RequireAcr = true; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10312:")); jwtWithSignatureChash.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Acr, "acr")); protocolValidator.RequireAmr = true; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10313:")); jwtWithSignatureChash.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Amr, "amr")); protocolValidator.RequireAuthTime = true; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10314:")); jwtWithSignatureChash.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.AuthTime, "authTime")); protocolValidator.RequireAzp = true; Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: new ExpectedException(typeExpected: typeof(OpenIdConnectProtocolException), substringExpected: "IDX10315:")); jwtWithSignatureChash.Payload.AddClaim(new Claim(JwtRegisteredClaimNames.Azp, "azp")); Validate(jwt: jwtWithSignatureChash, protocolValidator: protocolValidator, validationContext: validationContext, ee: ExpectedException.NoExceptionExpected); }