SOLR-14196: AdminUI login not working for JWTAuth when blockUnknown=false (#1190)

This commit is contained in:
Jan Høydahl 2020-01-23 14:51:36 +01:00 committed by GitHub
parent 84270dc6cf
commit e744f7977e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 4 deletions

View File

@ -238,6 +238,8 @@ Bug Fixes
an inability to assign a node based on existing autoscaling policy resulted in a server error instead of a bad request.
(Andras Salamon, Kevin Risden, shalin)
* SOLR-14196: AdminUI login not working for JWTAuth when blockUnknown=false (janhoy)
Other Changes
---------------------

View File

@ -338,6 +338,7 @@ public class JWTAuthPlugin extends AuthenticationPlugin implements SpecProvider,
if (log.isDebugEnabled())
log.debug("Unknown user, but allow due to {}=false", PARAM_BLOCK_UNKNOWN);
numPassThrough.inc();
request.setAttribute(AuthenticationPlugin.class.getName(), getPromptHeaders(null, null));
filterChain.doFilter(request, response);
return true;
@ -536,16 +537,28 @@ public class JWTAuthPlugin extends AuthenticationPlugin implements SpecProvider,
private enum BearerWwwAuthErrorCode { invalid_request, invalid_token, insufficient_scope}
private void authenticationFailure(HttpServletResponse response, String message, int httpCode, BearerWwwAuthErrorCode responseError) throws IOException {
getPromptHeaders(responseError, message).forEach(response::setHeader);
response.sendError(httpCode, message);
log.info("JWT Authentication attempt failed: {}", message);
}
/**
* Generate proper response prompt headers
* @param responseError standardized error code. Set to 'null' to generate WWW-Authenticate header with no error
* @param message custom message string to return in www-authenticate, or null if no error
* @return map of headers to add to response
*/
private Map<String, String> getPromptHeaders(BearerWwwAuthErrorCode responseError, String message) {
Map<String,String> headers = new HashMap<>();
List<String> wwwAuthParams = new ArrayList<>();
wwwAuthParams.add("Bearer realm=\"" + realm + "\"");
if (responseError != null) {
wwwAuthParams.add("error=\"" + responseError + "\"");
wwwAuthParams.add("error_description=\"" + message + "\"");
}
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, String.join(", ", wwwAuthParams));
response.addHeader(AuthenticationPlugin.HTTP_HEADER_X_SOLR_AUTHDATA, generateAuthDataHeader());
response.sendError(httpCode, message);
log.info("JWT Authentication attempt failed: {}", message);
headers.put(HttpHeaders.WWW_AUTHENTICATE, String.join(", ", wwwAuthParams));
headers.put(AuthenticationPlugin.HTTP_HEADER_X_SOLR_AUTHDATA, generateAuthDataHeader());
return headers;
}
protected String generateAuthDataHeader() {

View File

@ -0,0 +1,28 @@
{
"authentication": {
"class": "solr.JWTAuthPlugin",
"blockUnknown": false,
"jwk": {
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "test",
"alg": "RS256",
"n": "jeyrvOaZrmKWjyNXt0myAc_pJ1hNt3aRupExJEx1ewPaL9J9HFgSCjMrYxCB1ETO1NDyZ3nSgjZis-jHHDqBxBjRdq_t1E2rkGFaYbxAyKt220Pwgme_SFTB9MXVrFQGkKyjmQeVmOmV6zM3KK8uMdKQJ4aoKmwBcF5Zg7EZdDcKOFgpgva1Jq-FlEsaJ2xrYDYo3KnGcOHIt9_0NQeLsqZbeWYLxYni7uROFncXYV5FhSJCeR4A_rrbwlaCydGxE0ToC_9HNYibUHlkJjqyUhAgORCbNS8JLCJH8NUi5sDdIawK9GTSyvsJXZ-QHqo4cMUuxWV5AJtaRGghuMUfqQ"
},
"realm": "my-solr-jwt-blockunknown-false",
"adminUiScope": "solr:admin",
"authorizationEndpoint": "http://acmepaymentscorp/oauth/auz/authorize",
"clientId": "solr-cluster"
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [{
"name": "all",
"role": "*"
}],
"user-role": {
"solr": "solr-admin"
}
}
}

View File

@ -145,6 +145,28 @@ public class JWTAuthPluginIntegrationTest extends SolrCloudAuthTestCase {
" \"client_id\":\"solr-cluster\"}", authData);
}
@Test
public void infoRequestValidateXSolrAuthHeadersBlockUnknownFalse() throws Exception {
// Re-configure cluster with other security.json, see https://issues.apache.org/jira/browse/SOLR-14196
shutdownCluster();
configureCluster(NUM_SERVERS)// nodes
.withSecurityJson(TEST_PATH().resolve("security").resolve("jwt_plugin_jwk_security_blockUnknownFalse.json"))
.addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
.withDefaultClusterProperty("useLegacyReplicaAssignment", "false")
.configure();
baseUrl = cluster.getRandomJetty(random()).getBaseUrl().toString();
Map<String, String> headers = getHeaders(baseUrl + "/admin/info/system", null);
assertEquals("Should have received 401 code", "401", headers.get("code"));
assertEquals("Bearer realm=\"my-solr-jwt-blockunknown-false\"", headers.get("WWW-Authenticate"));
String authData = new String(Base64.base64ToByteArray(headers.get("X-Solr-AuthData")), UTF_8);
assertEquals("{\n" +
" \"scope\":\"solr:admin\",\n" +
" \"redirect_uris\":[],\n" +
" \"authorizationEndpoint\":\"http://acmepaymentscorp/oauth/auz/authorize\",\n" +
" \"client_id\":\"solr-cluster\"}", authData);
}
@Test
public void testMetrics() throws Exception {
boolean isUseV2Api = random().nextBoolean();