You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2019/07/15 09:43:29 UTC

[lucene-solr] 01/02: SOLR-13472: Forwarded requests should skip authorization on receiving nodes

This is an automated email from the ASF dual-hosted git repository.

ishan pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit a7a3fab8c881a4d5ad4ab56cd544052dcb22d073
Author: Ishan Chattopadhyaya <is...@apache.org>
AuthorDate: Mon Jul 15 14:43:41 2019 +0530

    SOLR-13472: Forwarded requests should skip authorization on receiving nodes
---
 solr/CHANGES.txt                                   |  2 +
 .../java/org/apache/solr/servlet/HttpSolrCall.java | 73 +++++++++++++---------
 2 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 7a86334..f960edf 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -196,6 +196,8 @@ Bug Fixes
 
 * SOLR-13532: Fix http timeout and error logging bugs in RecoveryStrategy. (Suril Shah, hossman)
 
+* SOLR-13472: Forwarded requests should skip authorization on receiving nodes (adfel, Ishan Chattopadhyaya)
+
 Other Changes
 ----------------------
 
diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
index 0ca46d0..2ed00f4 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -464,6 +464,35 @@ public class HttpSolrCall {
     }
   }
 
+  Action authorize() throws IOException {
+    AuthorizationContext context = getAuthCtx();
+    log.debug("AuthorizationContext : {}", context);
+    AuthorizationResponse authResponse = cores.getAuthorizationPlugin().authorize(context);
+    if (authResponse.statusCode == AuthorizationResponse.PROMPT.statusCode) {
+      Map<String, String> headers = (Map) getReq().getAttribute(AuthenticationPlugin.class.getName());
+      if (headers != null) {
+        for (Map.Entry<String, String> e : headers.entrySet()) response.setHeader(e.getKey(), e.getValue());
+      }
+      log.debug("USER_REQUIRED "+req.getHeader("Authorization")+" "+ req.getUserPrincipal());
+      if (shouldAudit(EventType.REJECTED)) {
+        cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.REJECTED, req, context));
+      }
+    }
+    if (!(authResponse.statusCode == HttpStatus.SC_ACCEPTED) && !(authResponse.statusCode == HttpStatus.SC_OK)) {
+      log.info("USER_REQUIRED auth header {} context : {} ", req.getHeader("Authorization"), context);
+      sendError(authResponse.statusCode,
+          "Unauthorized request, Response code: " + authResponse.statusCode);
+      if (shouldAudit(EventType.UNAUTHORIZED)) {
+        cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.UNAUTHORIZED, req, context));
+      }
+      return RETURN;
+    }
+    if (shouldAudit(EventType.AUTHORIZED)) {
+      cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.AUTHORIZED, req, context));
+    }
+    return null;
+  }
+  
   /**
    * This method processes the request.
    */
@@ -491,36 +520,20 @@ public class HttpSolrCall {
 
     try {
       init();
-      /* Authorize the request if
-       1. Authorization is enabled, and
-       2. The requested resource is not a known static file
-        */
-      if (cores.getAuthorizationPlugin() != null && shouldAuthorize()) {
-        AuthorizationContext context = getAuthCtx();
-        log.debug("AuthorizationContext : {}", context);
-        AuthorizationResponse authResponse = cores.getAuthorizationPlugin().authorize(context);
-        if (authResponse.statusCode == AuthorizationResponse.PROMPT.statusCode) {
-          Map<String, String> headers = (Map) getReq().getAttribute(AuthenticationPlugin.class.getName());
-          if (headers != null) {
-            for (Map.Entry<String, String> e : headers.entrySet()) response.setHeader(e.getKey(), e.getValue());
-          }
-          log.debug("USER_REQUIRED "+req.getHeader("Authorization")+" "+ req.getUserPrincipal());
-          if (shouldAudit(EventType.REJECTED)) {
-            cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.REJECTED, req, context));
-          }
-        }
-        if (!(authResponse.statusCode == HttpStatus.SC_ACCEPTED) && !(authResponse.statusCode == HttpStatus.SC_OK)) {
-          log.info("USER_REQUIRED auth header {} context : {} ", req.getHeader("Authorization"), context);
-          sendError(authResponse.statusCode,
-              "Unauthorized request, Response code: " + authResponse.statusCode);
-          if (shouldAudit(EventType.UNAUTHORIZED)) {
-            cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.UNAUTHORIZED, req, context));
-          }
-          return RETURN;
-        }
-        if (shouldAudit(EventType.AUTHORIZED)) {
-          cores.getAuditLoggerPlugin().doAudit(new AuditEvent(EventType.AUTHORIZED, req, context));
-        }
+
+      // Perform authorization here, if:
+      //    (a) Authorization is enabled, and
+      //    (b) The requested resource is not a known static file
+      //    (c) And this request should be handled by this node (see NOTE below)
+      // NOTE: If the query is to be handled by another node, then let that node do the authorization.
+      // In case of authentication using BasicAuthPlugin, for example, the internode request
+      // is secured using PKI authentication and the internode request here will contain the
+      // original user principal as a payload/header, using which the receiving node should be
+      // able to perform the authorization.
+      if (cores.getAuthorizationPlugin() != null && shouldAuthorize()
+          && !(action == REMOTEQUERY || action == FORWARD)) {
+        Action authorizationAction = authorize();
+        if (authorizationAction != null) return authorizationAction;
       }
 
       HttpServletResponse resp = response;