HADOOP-12929. JWTRedirectAuthenticationHandler must accommodate null expiration time. Contributed by Larry McCay.
This commit is contained in:
parent
680716f31e
commit
e7ed05e4f5
@ -26,20 +26,10 @@
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.text.ParseException;
|
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 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.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.CertificateUtil;
|
||||||
import org.apache.hadoop.security.authentication.util.KerberosName;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -83,7 +73,8 @@ public class JWTRedirectAuthenticationHandler extends
|
|||||||
private static Logger LOG = LoggerFactory
|
private static Logger LOG = LoggerFactory
|
||||||
.getLogger(JWTRedirectAuthenticationHandler.class);
|
.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 PUBLIC_KEY_PEM = "public.key.pem";
|
||||||
public static final String EXPECTED_JWT_AUDIENCES = "expected.jwt.audiences";
|
public static final String EXPECTED_JWT_AUDIENCES = "expected.jwt.audiences";
|
||||||
public static final String JWT_COOKIE_NAME = "jwt.cookie.name";
|
public static final String JWT_COOKIE_NAME = "jwt.cookie.name";
|
||||||
@ -205,7 +196,6 @@ public AuthenticationToken alternateAuthenticate(HttpServletRequest request,
|
|||||||
protected String getJWTFromCookie(HttpServletRequest req) {
|
protected String getJWTFromCookie(HttpServletRequest req) {
|
||||||
String serializedJWT = null;
|
String serializedJWT = null;
|
||||||
Cookie[] cookies = req.getCookies();
|
Cookie[] cookies = req.getCookies();
|
||||||
String userName = null;
|
|
||||||
if (cookies != null) {
|
if (cookies != null) {
|
||||||
for (Cookie cookie : cookies) {
|
for (Cookie cookie : cookies) {
|
||||||
if (cookieName.equals(cookie.getName())) {
|
if (cookieName.equals(cookie.getName())) {
|
||||||
@ -350,7 +340,7 @@ protected boolean validateExpiration(SignedJWT jwtToken) {
|
|||||||
boolean valid = false;
|
boolean valid = false;
|
||||||
try {
|
try {
|
||||||
Date expires = jwtToken.getJWTClaimsSet().getExpirationTime();
|
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 "
|
LOG.debug("JWT token expiration date has been "
|
||||||
+ "successfully validated");
|
+ "successfully validated");
|
||||||
valid = true;
|
valid = true;
|
||||||
|
@ -13,19 +13,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.hadoop.security.authentication.server;
|
package org.apache.hadoop.security.authentication.server;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.interfaces.RSAPrivateKey;
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@ -50,8 +46,6 @@
|
|||||||
import com.nimbusds.jwt.JWTClaimsSet;
|
import com.nimbusds.jwt.JWTClaimsSet;
|
||||||
import com.nimbusds.jwt.SignedJWT;
|
import com.nimbusds.jwt.SignedJWT;
|
||||||
import com.nimbusds.jose.crypto.RSASSASigner;
|
import com.nimbusds.jose.crypto.RSASSASigner;
|
||||||
import com.nimbusds.jose.crypto.RSASSAVerifier;
|
|
||||||
import com.nimbusds.jose.util.Base64URL;
|
|
||||||
|
|
||||||
public class TestJWTRedirectAuthentictionHandler extends
|
public class TestJWTRedirectAuthentictionHandler extends
|
||||||
KerberosSecurityTestcase {
|
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
|
@Test
|
||||||
public void testInvalidAudienceJWT() throws Exception {
|
public void testInvalidAudienceJWT() throws Exception {
|
||||||
try {
|
try {
|
||||||
@ -442,7 +466,6 @@ protected SignedJWT getJWT(String sub, Date expires, RSAPrivateKey privateKey)
|
|||||||
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).build();
|
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).build();
|
||||||
|
|
||||||
SignedJWT signedJWT = new SignedJWT(header, claimsSet);
|
SignedJWT signedJWT = new SignedJWT(header, claimsSet);
|
||||||
Base64URL sigInput = Base64URL.encode(signedJWT.getSigningInput());
|
|
||||||
JWSSigner signer = new RSASSASigner(privateKey);
|
JWSSigner signer = new RSASSASigner(privateKey);
|
||||||
|
|
||||||
signedJWT.sign(signer);
|
signedJWT.sign(signer);
|
||||||
|
Loading…
Reference in New Issue
Block a user