You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2017/05/13 16:47:25 UTC
knox git commit: KNOX-938 - JWTProvider to accept Query Param as well
as Bearer Token
Repository: knox
Updated Branches:
refs/heads/master fb2e31348 -> efc361ddc
KNOX-938 - JWTProvider to accept Query Param as well as Bearer Token
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/efc361dd
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/efc361dd
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/efc361dd
Branch: refs/heads/master
Commit: efc361ddc97209a2d87f69018701dbcc5a3450fc
Parents: fb2e313
Author: Larry McCay <lm...@hortonworks.com>
Authored: Sat May 13 12:47:03 2017 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Sat May 13 12:47:03 2017 -0400
----------------------------------------------------------------------
.../jwt/filter/JWTFederationFilter.java | 91 +++++++++++++-------
1 file changed, 61 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/efc361dd/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
index 33af374..9facd30 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
@@ -46,9 +46,11 @@ import java.util.Set;
public class JWTFederationFilter extends AbstractJWTFilter {
public static final String KNOX_TOKEN_AUDIENCES = "knox.token.audiences";
+ private static final String KNOX_TOKEN_QUERY_PARAM_NAME = "knox.token.query.param.name";
private static final String BEARER = "Bearer ";
private static JWTMessages log = MessagesFactory.get( JWTMessages.class );
private JWTokenAuthority authority = null;
+ private String paramName = "knoxtoken";
@Override
public void init( FilterConfig filterConfig ) throws ServletException {
@@ -60,6 +62,13 @@ public class JWTFederationFilter extends AbstractJWTFilter {
if (expectedAudiences != null) {
audiences = parseExpectedAudiences(expectedAudiences);
}
+
+ // query param name for finding the provided knoxtoken
+ String queryParamName = filterConfig.getInitParameter(KNOX_TOKEN_QUERY_PARAM_NAME);
+ if (queryParamName != null) {
+ paramName = queryParamName;
+ }
+
}
public void destroy() {
@@ -71,51 +80,73 @@ public class JWTFederationFilter extends AbstractJWTFilter {
if (header != null && header.startsWith(BEARER)) {
// what follows the bearer designator should be the JWT token being used to request or as an access token
String wireToken = header.substring(BEARER.length());
- JWTToken token;
- token = new JWTToken(wireToken);
- boolean verified = false;
- try {
- verified = authority.verifyToken(token);
- } catch (TokenServiceException e) {
- log.unableToVerifyToken(e);
+ JWTToken token = new JWTToken(wireToken);
+ if (validateToken(request, response, chain, token)) {
+ Subject subject = createSubjectFromToken(token);
+ continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain);
}
- if (verified) {
- // confirm that issue matches intended target - which for this filter must be KNOXSSO
- if (token.getIssuer().equals("KNOXSSO")) {
- // if there is no expiration data then the lifecycle is tied entirely to
- // the cookie validity - otherwise ensure that the current time is before
- // the designated expiration time
- if (tokenIsStillValid(token)) {
- boolean audValid = validateAudiences(token);
- if (audValid) {
- Subject subject = createSubjectFromToken(token);
- continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain);
- }
- else {
- log.failedToValidateAudience();
- ((HttpServletResponse) response).sendError(400, "Bad request: missing required token audience");
- }
+ else {
+ return; // break the filter chain
+ }
+ }
+ else {
+ // check for query param
+ String wireToken = ((HttpServletRequest) request).getParameter(paramName);
+ if (wireToken != null) {
+ JWTToken token = new JWTToken(wireToken);
+ if (validateToken(request, response, chain, token)) {
+ Subject subject = createSubjectFromToken(token);
+ continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain);
+ }
+ }
+ else {
+ // no token provided in header
+ ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return; //break filter chain
+ }
+ }
+ }
+
+ private boolean validateToken(ServletRequest request, ServletResponse response,
+ FilterChain chain, JWTToken token)
+ throws IOException, ServletException {
+ boolean rc = false;
+ boolean verified = false;
+ try {
+ verified = authority.verifyToken(token);
+ } catch (TokenServiceException e) {
+ log.unableToVerifyToken(e);
+ }
+ if (verified) {
+ // confirm that issue matches intended target - which for this filter must be KNOXSSO
+ if (token.getIssuer().equals("KNOXSSO")) {
+ // if there is no expiration data then the lifecycle is tied entirely to
+ // the cookie validity - otherwise ensure that the current time is before
+ // the designated expiration time
+ if (tokenIsStillValid(token)) {
+ boolean audValid = validateAudiences(token);
+ if (audValid) {
+ rc = true;
}
else {
- log.tokenHasExpired();
- ((HttpServletResponse) response).sendError(400, "Bad request: token has expired");
+ log.failedToValidateAudience();
+ ((HttpServletResponse) response).sendError(400, "Bad request: missing required token audience");
}
}
else {
- ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return; //break filter chain
+ log.tokenHasExpired();
+ ((HttpServletResponse) response).sendError(400, "Bad request: token has expired");
}
}
else {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return; //break filter chain
}
}
else {
- // no token provided in header
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return; //break filter chain
}
+
+ return rc;
}
private void continueWithEstablishedSecurityContext(Subject subject, final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {