HADOOP-12929. JWTRedirectAuthenticationHandler must accommodate null expiration time. Contributed by Larry McCay.

This commit is contained in:
Benoy Antony 2016-03-21 13:19:43 -07:00
parent 680716f31e
commit e7ed05e4f5
2 changed files with 33 additions and 20 deletions

View File

@ -26,20 +26,10 @@
import java.util.Properties;
import java.text.ParseException;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.interfaces.RSAPublicKey;
import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authentication.server.AltKerberosAuthenticationHandler;
import org.apache.hadoop.security.authentication.server.AuthenticationToken;
import org.apache.hadoop.security.authentication.util.CertificateUtil;
import org.apache.hadoop.security.authentication.util.KerberosName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -83,7 +73,8 @@ public class JWTRedirectAuthenticationHandler extends
private static Logger LOG = LoggerFactory
.getLogger(JWTRedirectAuthenticationHandler.class);
public static final String AUTHENTICATION_PROVIDER_URL = "authentication.provider.url";
public static final String AUTHENTICATION_PROVIDER_URL =
"authentication.provider.url";
public static final String PUBLIC_KEY_PEM = "public.key.pem";
public static final String EXPECTED_JWT_AUDIENCES = "expected.jwt.audiences";
public static final String JWT_COOKIE_NAME = "jwt.cookie.name";
@ -205,7 +196,6 @@ public AuthenticationToken alternateAuthenticate(HttpServletRequest request,
protected String getJWTFromCookie(HttpServletRequest req) {
String serializedJWT = null;
Cookie[] cookies = req.getCookies();
String userName = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName())) {
@ -350,7 +340,7 @@ protected boolean validateExpiration(SignedJWT jwtToken) {
boolean valid = false;
try {
Date expires = jwtToken.getJWTClaimsSet().getExpirationTime();
if (expires != null && new Date().before(expires)) {
if (expires == null || new Date().before(expires)) {
LOG.debug("JWT token expiration date has been "
+ "successfully validated");
valid = true;

View File

@ -13,19 +13,15 @@
*/
package org.apache.hadoop.security.authentication.server;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
@ -50,8 +46,6 @@
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.util.Base64URL;
public class TestJWTRedirectAuthentictionHandler extends
KerberosSecurityTestcase {
@ -261,6 +255,36 @@ public void testExpiredJWT() throws Exception {
}
}
@Test
public void testNoExpirationJWT() throws Exception {
try {
handler.setPublicKey(publicKey);
Properties props = getProperties();
handler.init(props);
SignedJWT jwt = getJWT("bob", null, privateKey);
Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
Mockito.when(request.getCookies()).thenReturn(new Cookie[] { cookie });
Mockito.when(request.getRequestURL()).thenReturn(
new StringBuffer(SERVICE_URL));
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(response.encodeRedirectURL(SERVICE_URL)).thenReturn(
SERVICE_URL);
AuthenticationToken token = handler.alternateAuthenticate(request,
response);
Assert.assertNotNull("Token should not be null.", token);
Assert.assertEquals("bob", token.getUserName());
} catch (ServletException se) {
fail("alternateAuthentication should NOT have thrown a ServletException");
} catch (AuthenticationException ae) {
fail("alternateAuthentication should NOT have thrown a AuthenticationException");
}
}
@Test
public void testInvalidAudienceJWT() throws Exception {
try {
@ -442,7 +466,6 @@ protected SignedJWT getJWT(String sub, Date expires, RSAPrivateKey privateKey)
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).build();
SignedJWT signedJWT = new SignedJWT(header, claimsSet);
Base64URL sigInput = Base64URL.encode(signedJWT.getSigningInput());
JWSSigner signer = new RSASSASigner(privateKey);
signedJWT.sign(signer);