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 2017/03/18 17:32:13 UTC
lucene-solr:jira/solr-6736: SOLR-6736: Overhaul of authorization
response and RuleBasedAuthorizationPlugin
Repository: lucene-solr
Updated Branches:
refs/heads/jira/solr-6736 a2931a147 -> 4d6d8238d
SOLR-6736: Overhaul of authorization response and RuleBasedAuthorizationPlugin
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/4d6d8238
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/4d6d8238
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/4d6d8238
Branch: refs/heads/jira/solr-6736
Commit: 4d6d8238da15b9a096a3ee288f25c38e37229b41
Parents: a2931a1
Author: Ishan Chattopadhyaya <is...@apache.org>
Authored: Sat Mar 18 23:02:01 2017 +0530
Committer: Ishan Chattopadhyaya <is...@apache.org>
Committed: Sat Mar 18 23:02:01 2017 +0530
----------------------------------------------------------------------
.../solr/handler/admin/ConfigSetsHandler.java | 44 ++++++++++++--------
.../solr/security/AuthorizationResponse.java | 19 +++++++--
.../security/RuleBasedAuthorizationPlugin.java | 44 +++++++++++---------
.../org/apache/solr/servlet/HttpSolrCall.java | 9 +++-
.../solr/security/MockAuthorizationPlugin.java | 8 ++--
5 files changed, 77 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4d6d8238/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
index 8b76912..5d78af0 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ConfigSetsHandler.java
@@ -60,7 +60,10 @@ import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.AuthorizationContext;
+import org.apache.solr.security.AuthorizationPlugin;
+import org.apache.solr.security.AuthorizationResponse;
import org.apache.solr.security.PermissionNameProvider;
+import org.apache.solr.security.RuleBasedAuthorizationPlugin;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
@@ -170,23 +173,7 @@ public class ConfigSetsHandler extends RequestHandlerBase implements PermissionN
InputStream inputStream = contentStreamsIterator.next().getStream();
// Create a node for the configuration in zookeeper nocommit: do this only if /admin is not protected by authz/authc
- boolean trusted = false;
- /*AuthorizationPlugin authz = coreContainer.getAuthorizationPlugin();
- if (authz == null) {
- trusted = false;
- } else {
- if (authz instanceof RuleBasedAuthorizationPlugin) {
- List<Permission> permissions = ((RuleBasedAuthorizationPlugin) authz).getPermissions("/admin/config");
- System.out.println("Permissions for this path: "+permissions);
- if (permissions.isEmpty()) {
- trusted = false;
- } else {
- trusted = true;
- }
- } else {
- trusted = true;
- }
- }*/
+ boolean trusted = getTrusted(req);
zkClient.makePath(configPathInZk, ("{\"trusted\": "+Boolean.toString(trusted)+"}").getBytes(StandardCharsets.UTF_8), true);
ZipInputStream zis = new ZipInputStream(inputStream, StandardCharsets.UTF_8);
@@ -206,7 +193,28 @@ public class ConfigSetsHandler extends RequestHandlerBase implements PermissionN
rsp.add("message", configSetName + " successfully uploaded!");
}
- private void createZkNodeIfNotExistsAndSetData(SolrZkClient zkClient,
+ boolean getTrusted(SolrQueryRequest req) {
+ AuthorizationPlugin authzPlugin = coreContainer.getAuthorizationPlugin();
+ AuthorizationResponse authzResponse = req.getHttpSolrCall().getAuthorizationResponse();
+
+ System.out.println("Authz plugin: "+authzPlugin);
+ System.out.println("Authz permission: "+authzResponse.getPermission());
+ if (authzPlugin != null) {
+ if (authzPlugin instanceof RuleBasedAuthorizationPlugin) {
+ if (authzResponse.getPermission() == null) { // this request was permitted since this endpoint was not protected
+ return false;
+ } else {
+ return true; // there was a particular permission that passed, and hence this endpoint is protected
+ }
+ } else {
+ return true; // trust all other authz plugins to have done the authorization properly
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private void createZkNodeIfNotExistsAndSetData(SolrZkClient zkClient,
String filePathInZk, byte[] data) throws Exception {
if (!zkClient.exists(filePathInZk, true)) {
zkClient.create(filePathInZk, data, CreateMode.PERSISTENT, true);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4d6d8238/solr/core/src/java/org/apache/solr/security/AuthorizationResponse.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/AuthorizationResponse.java b/solr/core/src/java/org/apache/solr/security/AuthorizationResponse.java
index 6c84489..5e756b0 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthorizationResponse.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthorizationResponse.java
@@ -20,14 +20,21 @@ package org.apache.solr.security;
be used to return ACLs and other information from the authorization plugin.
*/
public class AuthorizationResponse {
- public static final AuthorizationResponse OK = new AuthorizationResponse(200);
- public static final AuthorizationResponse FORBIDDEN = new AuthorizationResponse(403);
- public static final AuthorizationResponse PROMPT = new AuthorizationResponse(401);
+ public static final int OK_STATUS = 200;
+ public static final int FORBIDDEN_STATUS = 403;
+ public static final int PROMPT_STATUS = 401;
+
public final int statusCode;
+
+ /**
+ * nocommit javadocs
+ */
+ private final Permission permission;
String message;
- public AuthorizationResponse(int httpStatusCode) {
+ public AuthorizationResponse(int httpStatusCode, Permission permission) {
this.statusCode = httpStatusCode;
+ this.permission = permission;
}
public String getMessage() {
@@ -37,4 +44,8 @@ public class AuthorizationResponse {
public void setMessage(String message) {
this.message = message;
}
+
+ public Permission getPermission() {
+ return permission;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4d6d8238/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPlugin.java b/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPlugin.java
index 7e3b7ab..398af16 100644
--- a/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPlugin.java
@@ -99,32 +99,34 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
public AuthorizationResponse authorize(AuthorizationContext context) {
List<AuthorizationContext.CollectionRequest> collectionRequests = context.getCollectionRequests();
if (context.getRequestType() == AuthorizationContext.RequestType.ADMIN) {
- MatchStatus flag = checkCollPerm(mapping.get(null), context);
- return flag.rsp;
+ return checkCollPerm(mapping.get(null), context);
}
for (AuthorizationContext.CollectionRequest collreq : collectionRequests) {
//check permissions for each collection
- MatchStatus flag = checkCollPerm(mapping.get(collreq.collectionName), context);
- if (flag != MatchStatus.NO_PERMISSIONS_FOUND) return flag.rsp;
+ AuthorizationResponse rsp = checkCollPerm(mapping.get(collreq.collectionName), context);
+ if (rsp.getPermission() == null) return rsp;
}
//check wildcard (all=*) permissions.
- MatchStatus flag = checkCollPerm(mapping.get("*"), context);
- return flag.rsp;
+ return checkCollPerm(mapping.get("*"), context);
}
- private MatchStatus checkCollPerm(Map<String, List<Permission>> pathVsPerms,
+ private AuthorizationResponse checkCollPerm(Map<String, List<Permission>> pathVsPerms,
AuthorizationContext context) {
- if (pathVsPerms == null) return MatchStatus.NO_PERMISSIONS_FOUND;
+ if (pathVsPerms == null) {
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, null);
+ }
String path = context.getResource();
- MatchStatus flag = checkPathPerm(pathVsPerms.get(path), context);
- if (flag != MatchStatus.NO_PERMISSIONS_FOUND) return flag;
+ AuthorizationResponse rsp = checkPathPerm(pathVsPerms.get(path), context);
+ if (rsp.getPermission() != null) return rsp;
return checkPathPerm(pathVsPerms.get(null), context);
}
- private MatchStatus checkPathPerm(List<Permission> permissions, AuthorizationContext context) {
- if (permissions == null || permissions.isEmpty()) return MatchStatus.NO_PERMISSIONS_FOUND;
+ private AuthorizationResponse checkPathPerm(List<Permission> permissions, AuthorizationContext context) {
+ if (permissions == null || permissions.isEmpty()) {
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, null);
+ }
Principal principal = context.getUserPrincipal();
loopPermissions:
for (int i = 0; i < permissions.size(); i++) {
@@ -155,26 +157,28 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
if (permission.role == null) {
//no role is assigned permission.That means everybody is allowed to access
- return MatchStatus.PERMITTED;
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, permission);
}
if (principal == null) {
log.info("request has come without principal. failed permission {} ",permission);
//this resource needs a principal but the request has come without
//any credential.
- return MatchStatus.USER_REQUIRED;
+ return new AuthorizationResponse(AuthorizationResponse.PROMPT_STATUS, permission);
} else if (permission.role.contains("*")) {
- return MatchStatus.PERMITTED;
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, permission);
}
for (String role : permission.role) {
Set<String> userRoles = usersVsRoles.get(principal.getName());
- if (userRoles != null && userRoles.contains(role)) return MatchStatus.PERMITTED;
+ if (userRoles != null && userRoles.contains(role)) {
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, permission); //nocommit should we send the role as well?
+ }
}
log.info("This resource is configured to have a permission {}, The principal {} does not have the right role ", permission, principal);
- return MatchStatus.FORBIDDEN;
+ return new AuthorizationResponse(AuthorizationResponse.FORBIDDEN_STATUS, permission);
}
log.debug("No permissions configured for the resource {} . So allowed to access", context.getResource());
- return MatchStatus.NO_PERMISSIONS_FOUND;
+ return new AuthorizationResponse(AuthorizationResponse.OK_STATUS, null);
}
@Override
@@ -217,7 +221,7 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
@Override
public void close() throws IOException { }
- enum MatchStatus {
+ /*enum MatchStatus {
USER_REQUIRED(AuthorizationResponse.PROMPT),
NO_PERMISSIONS_FOUND(AuthorizationResponse.OK),
PERMITTED(AuthorizationResponse.OK),
@@ -228,7 +232,7 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
MatchStatus(AuthorizationResponse rsp) {
this.rsp = rsp;
}
- }
+ }*/
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4d6d8238/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
----------------------------------------------------------------------
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 3f69c15..0a54f40 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -461,6 +461,12 @@ public class HttpSolrCall {
}
}
+ private AuthorizationResponse authorizationResponse = null;
+
+ public AuthorizationResponse getAuthorizationResponse() {
+ return authorizationResponse;
+ }
+
/**
* This method processes the request.
*/
@@ -488,7 +494,8 @@ public class HttpSolrCall {
AuthorizationContext context = getAuthorizationContext();
log.debug("AuthorizationContext : {}", context);
AuthorizationResponse authResponse = cores.getAuthorizationPlugin().authorize(context);
- if (authResponse.statusCode == AuthorizationResponse.PROMPT.statusCode) {
+ this.authorizationResponse = authResponse; // downstream processing might need this
+ if (authResponse.statusCode == AuthorizationResponse.PROMPT_STATUS) {
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());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4d6d8238/solr/core/src/test/org/apache/solr/security/MockAuthorizationPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/MockAuthorizationPlugin.java b/solr/core/src/test/org/apache/solr/security/MockAuthorizationPlugin.java
index 1cbe849..8d8d99a 100644
--- a/solr/core/src/test/org/apache/solr/security/MockAuthorizationPlugin.java
+++ b/solr/core/src/test/org/apache/solr/security/MockAuthorizationPlugin.java
@@ -38,9 +38,9 @@ public class MockAuthorizationPlugin implements AuthorizationPlugin {
if (predicate != null) {
try {
predicate.test(context);
- return new AuthorizationResponse(200);
+ return new AuthorizationResponse(200, null);
} catch (SolrException e) {
- return new AuthorizationResponse(e.code());
+ return new AuthorizationResponse(e.code(), null);
}
}
@@ -48,9 +48,9 @@ public class MockAuthorizationPlugin implements AuthorizationPlugin {
if (uname == null) uname = context.getParams().get("uname");
log.info("User request: " + uname);
if (denyUsers.contains(uname))
- return new AuthorizationResponse(403);
+ return new AuthorizationResponse(403, null);
else
- return new AuthorizationResponse(200);
+ return new AuthorizationResponse(200, null);
}
@Override