madrob commented on a change in pull request #139:
URL: https://github.com/apache/solr/pull/139#discussion_r636972401



##########
File path: solr/core/src/java/org/apache/solr/security/JWTAuthPlugin.java
##########
@@ -199,6 +237,28 @@ public void init(Map<String, Object> pluginConfig) {
     lastInitTime = Instant.now();
   }
 
+  /**
+   * Tries for find X509 certificates in the input stream in DER or PEM format.
+   * Supports multiple certs in same stream if multiple PEM certs are 
concatenated.
+   * @param trustedCertsStream input stream with the contents of either PEM 
(plaintext) or DER (binary) certs
+   * @return collection of found certificates, else throws exception
+   */
+  static Collection<X509Certificate> parsePemToX509Certs(InputStream 
trustedCertsStream) {

Review comment:
       Maybe this belongs in CryptoKeys? Or some other util class?

##########
File path: solr/core/src/java/org/apache/solr/security/JWTIssuerConfig.java
##########
@@ -335,33 +346,49 @@ public boolean isValid() {
     return jwkConfigured > 0;
   }
 
+  public void setTrustedCerts(Collection<X509Certificate> trustedCerts) {
+    this.trustedCerts = trustedCerts;
+  }
+
   /**
    *
    */
   static class HttpsJwksFactory {
     private final long jwkCacheDuration;
     private final long refreshReprieveThreshold;
+    private Collection<X509Certificate> trustedCerts;
 
     public HttpsJwksFactory(long jwkCacheDuration, long 
refreshReprieveThreshold) {
       this.jwkCacheDuration = jwkCacheDuration;
       this.refreshReprieveThreshold = refreshReprieveThreshold;
     }
-    
+
+    public HttpsJwksFactory(long jwkCacheDuration, long 
refreshReprieveThreshold, Collection<X509Certificate> trustedCerts) {
+      this.jwkCacheDuration = jwkCacheDuration;
+      this.refreshReprieveThreshold = refreshReprieveThreshold;
+      this.trustedCerts = trustedCerts;
+    }
+
     /**
      * While the class name is HttpsJwks, it actually works with plain http 
formatted url as well.
+     *
      * @param url the Url to connect to for JWK details.
      */
     private HttpsJwks create(String url) {
       try {
         URL jwksUrl = new URL(url);
         checkAllowOutboundHttpConnections(PARAM_JWKS_URL, jwksUrl);
-        
       } catch (MalformedURLException e) {
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Url " + 
url + " configured in " + PARAM_JWKS_URL + " is not a valid URL");
       }
       HttpsJwks httpsJkws = new HttpsJwks(url);
       httpsJkws.setDefaultCacheDuration(jwkCacheDuration);
       httpsJkws.setRefreshReprieveThreshold(refreshReprieveThreshold);
+      if (trustedCerts != null) {
+        Get getWithCustomTrust = new Get();
+        getWithCustomTrust.setTrustedCertificates(trustedCerts);
+        log.info("Trusting custom SSL certificate(s) for the IdP");

Review comment:
       How often does this happen? Is it per user request? Per user session? 
Might be too verbose.

##########
File path: solr/solr-ref-guide/src/jwt-authentication-plugin.adoc
##########
@@ -54,6 +54,8 @@ rolesClaim           ; What claim id to pull user roles from. 
The claim must the
 claimsMatch          ; JSON object of claims (key) that must match a regular 
expression (value). Example: `{ "foo" : "A|B" }` will require the `foo` claim 
to be either "A" or "B". ;
 adminUiScope         ; Define what scope is requested when logging in from 
Admin UI ; If not defined, the first scope from `scope` parameter is used
 redirectUris         ; Valid location(s) for redirect after external 
authentication. Takes a string or array of strings. Must be the base URL of 
Solr, e.g., https://solr1.example.com:8983/solr/ and must match the list of 
redirect URIs registered with the Identity Provider beforehand. ; Defaults to 
empty list, i.e., any node is assumed to be a valid redirect target.
+trustedCerts         ; One or more X.509 SSL certificates in plaintext PEM or 
PKCS#7 formats, that should be trusted when talking to IdPs. Newlines must be 
replaced with `\n`. ; Defaults to Java truststore

Review comment:
       I'd like to see more explanation when somebody would need this, similar 
to what was described in the JIRA, e.g. explain that Jetty's TrustStore is 
ignored if running with HTTP with an SSL-terminating proxy/LB/ingress in front.

##########
File path: solr/core/src/test/org/apache/solr/security/JWTAuthPluginTest.java
##########
@@ -477,4 +484,51 @@ public void initWithToplevelAndIssuersCombined() {
     // Top-level (name=PRIMARY) issuer config does not need "iss" for back 
compat
     assertNull(plugin.getPrimaryIssuer().getIss());
   }
+
+  @Test
+  public void initWithIdpCertString() {
+    HashMap<String, Object> authConf = new HashMap<>();
+    authConf.put("jwksUrl", "https://127.0.0.1:9999/foo.jwk";);
+    authConf.put("trustedCerts", trustedPemCert);
+    plugin = new JWTAuthPlugin();
+    plugin.init(authConf);
+  }
+
+  @Test
+  public void initWithIdpCertPath() {
+    HashMap<String, Object> authConf = new HashMap<>();
+    authConf.put("jwksUrl", "https://127.0.0.1:9999/foo.jwk";);
+    authConf.put("trustedCertsFile", 
TEST_PATH().resolve("security").resolve("jwt_idpCert.pem").toString());
+    plugin = new JWTAuthPlugin();
+    plugin.init(authConf);

Review comment:
       Anything we can do to assert that the generated factory has the correct 
trust store?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to