Repository: ambari Updated Branches: refs/heads/trunk 21984fcc4 -> 7bdfd3b54
AMBARI-16638. Empty audiences list is treated as deny all for JWT auth. (mpapirkovskyy) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7bdfd3b5 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7bdfd3b5 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7bdfd3b5 Branch: refs/heads/trunk Commit: 7bdfd3b542a80510e91a94072161a63a2c488bc2 Parents: 21984fc Author: Myroslav Papirkovskyi <mpapyrkovs...@hortonworks.com> Authored: Thu May 12 18:29:40 2016 +0300 Committer: Myroslav Papirkovskyi <mpapyrkovs...@hortonworks.com> Committed: Thu May 12 18:33:21 2016 +0300 ---------------------------------------------------------------------- .../jwt/JwtAuthenticationFilter.java | 5 +- .../jwt/JwtAuthenticationProperties.java | 4 +- .../jwt/JwtAuthenticationFilterTest.java | 43 +++++++++++++++-- .../jwt/JwtAuthenticationPropertiesTest.java | 51 ++++++++++++++++++++ 4 files changed, 96 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/7bdfd3b5/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilter.java index a097df1..7347e73 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilter.java @@ -320,7 +320,10 @@ public class JwtAuthenticationFilter implements Filter { } else { // if any of the configured audiences is found then consider it // acceptable - boolean found = false; + if (tokenAudienceList == null) { + LOG.warn("JWT token has no audiences, validation failed."); + return false; + } for (String aud : tokenAudienceList) { if (audiences.contains(aud)) { LOG.debug("JWT token audience has been successfully validated"); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bdfd3b5/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationProperties.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationProperties.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationProperties.java index d237a95..e36dd56 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationProperties.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationProperties.java @@ -17,6 +17,8 @@ */ package org.apache.ambari.server.security.authorization.jwt; +import org.apache.commons.lang.StringUtils; + import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collections; @@ -57,7 +59,7 @@ public class JwtAuthenticationProperties { } public void setAudiencesString(String audiencesString) { - if (audiencesString != null) { + if (StringUtils.isNotEmpty(audiencesString)) { // parse into the list String[] audArray = audiencesString.split(","); audiences = new ArrayList<String>(); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bdfd3b5/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilterTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilterTest.java index 4999bb3..a2730c4 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilterTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationFilterTest.java @@ -51,6 +51,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; +import java.util.List; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMockBuilder; @@ -81,22 +82,30 @@ public class JwtAuthenticationFilterTest { } private JwtAuthenticationProperties createTestProperties() { + return createTestProperties(Collections.singletonList("test-audience")); + } + + private JwtAuthenticationProperties createTestProperties(List<String> audiences) { JwtAuthenticationProperties properties = new JwtAuthenticationProperties(); properties.setCookieName("non-default"); properties.setPublicKey(publicKey); - properties.setAudiences(Collections.singletonList("test-audience")); + properties.setAudiences(audiences); return properties; } private SignedJWT getSignedToken() throws JOSEException { + return getSignedToken("test-audience"); + } + + private SignedJWT getSignedToken(String audience) throws JOSEException { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.DATE, 1); //add one day - return getSignedToken(calendar.getTime()); + return getSignedToken(calendar.getTime(), audience); } - private SignedJWT getSignedToken(Date expirationTime) throws JOSEException { + private SignedJWT getSignedToken(Date expirationTime, String audience) throws JOSEException { RSASSASigner signer = new RSASSASigner(privateKey); Calendar calendar = Calendar.getInstance(); @@ -108,7 +117,7 @@ public class JwtAuthenticationFilterTest { claimsSet.setExpirationTime(expirationTime); - claimsSet.setAudience("test-audience"); + claimsSet.setAudience(audience); SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet); signedJWT.sign(signer); @@ -233,6 +242,30 @@ public class JwtAuthenticationFilterTest { } @Test + public void testValidateNullAudiences() throws Exception { + JwtAuthenticationProperties properties = createTestProperties(null); + JwtAuthenticationFilter filter = new JwtAuthenticationFilter(properties, null, null); + + boolean isValid = filter.validateAudiences(getSignedToken()); + + assertEquals(true, isValid); + + isValid = filter.validateAudiences(getInvalidToken()); + + assertEquals(true, isValid); + } + + @Test + public void testValidateTokenWithoutAudiences() throws Exception { + JwtAuthenticationProperties properties = createTestProperties(); + JwtAuthenticationFilter filter = new JwtAuthenticationFilter(properties, null, null); + + boolean isValid = filter.validateAudiences(getSignedToken(null)); + + assertEquals(false, isValid); + } + + @Test public void testValidateExpiration() throws Exception { JwtAuthenticationProperties properties = createTestProperties(); JwtAuthenticationFilter filter = new JwtAuthenticationFilter(properties, null, null); @@ -252,7 +285,7 @@ public class JwtAuthenticationFilterTest { JwtAuthenticationProperties properties = createTestProperties(); JwtAuthenticationFilter filter = new JwtAuthenticationFilter(properties, null, null); - boolean isValid = filter.validateExpiration(getSignedToken(null)); + boolean isValid = filter.validateExpiration(getSignedToken(null, "test-audience")); assertEquals(true, isValid); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bdfd3b5/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationPropertiesTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationPropertiesTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationPropertiesTest.java new file mode 100644 index 0000000..a2109a2 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/jwt/JwtAuthenticationPropertiesTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.security.authorization.jwt; + +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class JwtAuthenticationPropertiesTest { + + @Test + public void testSetNullAudiences() { + JwtAuthenticationProperties jwtAuthenticationProperties = new JwtAuthenticationProperties(); + jwtAuthenticationProperties.setAudiencesString(null); + assertNull(jwtAuthenticationProperties.getAudiences()); + } + + @Test + public void testSetEmptyAudiences() { + JwtAuthenticationProperties jwtAuthenticationProperties = new JwtAuthenticationProperties(); + jwtAuthenticationProperties.setAudiencesString(""); + assertNull(jwtAuthenticationProperties.getAudiences()); + } + + @Test + public void testSetValidAudiences() { + String[] expectedAudiences = {"first", "second", "third"}; + JwtAuthenticationProperties jwtAuthenticationProperties = new JwtAuthenticationProperties(); + jwtAuthenticationProperties.setAudiencesString("first,second,third"); + assertNotNull(jwtAuthenticationProperties.getAudiences()); + assertArrayEquals(expectedAudiences, jwtAuthenticationProperties.getAudiences().toArray(new String[]{})); + } +}