Fix null check for JWT claims (#14872)

This commit is contained in:
Atul Mohan 2023-08-23 02:09:23 -07:00 committed by GitHub
parent 76e5048aab
commit 989ed8d0c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 1 deletions

View File

@ -83,7 +83,7 @@ public class JwtAuthFilter implements Filter
// Parses the JWT and performs the ID Token validation specified in the OpenID spec: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
IDTokenClaimsSet claims = tokenValidator.validate(JWTParser.parse(idToken.get()), null);
if (claims != null) {
Optional<String> claim = Optional.of(claims.getStringClaim(oidcConfig.getOidcClaim()));
Optional<String> claim = Optional.ofNullable(claims.getStringClaim(oidcConfig.getOidcClaim()));
if (claim.isPresent()) {
LOG.debug("Authentication successful for " + oidcConfig.getClientID());

View File

@ -20,7 +20,13 @@
package org.apache.druid.security.pac4j;
import com.google.common.collect.ImmutableMap;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.proc.BadJOSEException;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.oauth2.sdk.id.Subject;
import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet;
import org.apache.druid.server.security.AuthConfig;
import org.apache.druid.server.security.AuthenticationResult;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
@ -31,9 +37,12 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
public class JwtAuthenticatorTest
{
private static final String DUMMY_BEARER_TOKEN_HEADER = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
@Test
public void testBearerToken()
throws IOException, ServletException
@ -87,4 +96,91 @@ public class JwtAuthenticatorTest
EasyMock.verify(req, resp, filterChain);
}
@Test
public void testValidClaim()
throws IOException, ServletException, BadJOSEException, JOSEException
{
HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)).andReturn(null);
EasyMock.expect(req.getHeader("Authorization")).andReturn(DUMMY_BEARER_TOKEN_HEADER);
req.setAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT, new AuthenticationResult("foo", "allowAll", "jwt", null));
EasyMock.expectLastCall().times(1);
EasyMock.replay(req);
OIDCConfig configuration = EasyMock.createMock(OIDCConfig.class);
EasyMock.expect(configuration.getOidcClaim()).andReturn("iss");
EasyMock.expect(configuration.getClientID()).andReturn("testClient");
EasyMock.replay(configuration);
TokenValidator tokenValidator = EasyMock.createMock(TokenValidator.class);
EasyMock.expect(tokenValidator.validate(EasyMock.anyObject(), EasyMock.anyObject()))
.andReturn(new IDTokenClaimsSet(new Issuer("foo"),
new Subject("testsub"),
Collections.emptyList(),
null,
null
));
EasyMock.replay(tokenValidator);
HttpServletResponse resp = EasyMock.createMock(HttpServletResponse.class);
EasyMock.replay(resp);
FilterChain filterChain = EasyMock.createMock(FilterChain.class);
filterChain.doFilter(req, resp);
EasyMock.expectLastCall().times(1);
EasyMock.replay(filterChain);
JwtAuthenticator jwtAuthenticator = new JwtAuthenticator("jwt", "allowAll", configuration);
JwtAuthFilter authFilter = new JwtAuthFilter("allowAll", "jwt", configuration, tokenValidator);
authFilter.doFilter(req, resp, filterChain);
EasyMock.verify(req, resp, filterChain);
Assert.assertEquals(jwtAuthenticator.getFilterClass(), JwtAuthFilter.class);
Assert.assertNull(jwtAuthenticator.getInitParameters());
Assert.assertNull(jwtAuthenticator.authenticateJDBCContext(ImmutableMap.of()));
}
@Test
public void testEmptyClaim()
throws IOException, ServletException, BadJOSEException, JOSEException
{
OIDCConfig configuration = EasyMock.createMock(OIDCConfig.class);
HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)).andReturn(null);
EasyMock.expect(req.getHeader("Authorization")).andReturn(DUMMY_BEARER_TOKEN_HEADER);
EasyMock.replay(req);
TokenValidator tokenValidator = EasyMock.createMock(TokenValidator.class);
// This doesn't return any claims for the default scope
EasyMock.expect(tokenValidator.validate(EasyMock.anyObject(), EasyMock.anyObject()))
.andReturn(new IDTokenClaimsSet(new Issuer("test"),
new Subject("testsub"),
Collections.emptyList(),
null,
null
));
EasyMock.replay(tokenValidator);
HttpServletResponse resp = EasyMock.createMock(HttpServletResponse.class);
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
EasyMock.expectLastCall().times(1);
EasyMock.replay(resp);
FilterChain filterChain = EasyMock.createMock(FilterChain.class);
EasyMock.replay(filterChain);
JwtAuthenticator jwtAuthenticator = new JwtAuthenticator("jwt", "allowAll", configuration);
JwtAuthFilter authFilter = new JwtAuthFilter("allowAll", "jwt", configuration, tokenValidator);
authFilter.doFilter(req, resp, filterChain);
EasyMock.verify(req, resp, filterChain);
Assert.assertEquals(jwtAuthenticator.getFilterClass(), JwtAuthFilter.class);
Assert.assertNull(jwtAuthenticator.getInitParameters());
Assert.assertNull(jwtAuthenticator.authenticateJDBCContext(ImmutableMap.of()));
}
}