in security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKrbFilter.java [271:442]
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
boolean unauthorizedResponse = true;
int errCode = HttpServletResponse.SC_UNAUTHORIZED;
AuthenticationException authenticationEx = null;
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
boolean isHttps = "https".equals(httpRequest.getScheme());
boolean allowTrustedProxy = PropertiesUtil.getBooleanProperty(ALLOW_TRUSTED_PROXY, false);
long contentLength = httpRequest.getContentLength();
try {
boolean newToken = false;
AuthenticationToken token;
try {
token = getToken(httpRequest);
} catch (AuthenticationException ex) {
ex.printStackTrace();
LOG.warn("AuthenticationToken ignored: {}", ex.getMessage());
// will be sent back in a 401 unless filter authenticates
authenticationEx = ex;
token = null;
}
if (authHandler.managementOperation(token, httpRequest, httpResponse)) {
if (token == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Request [{}] triggering authentication", getRequestURL(httpRequest));
}
token = authHandler.authenticate(httpRequest, httpResponse);
if (token != null && token.getExpires() != 0 && token != AuthenticationToken.ANONYMOUS) {
token.setExpires(System.currentTimeMillis() + getValidity() * 1000);
}
newToken = true;
}
if (token != null) {
unauthorizedResponse = false;
if (LOG.isDebugEnabled()) {
LOG.debug("Request [{}] user [{}] authenticated", getRequestURL(httpRequest), token.getUserName());
}
final AuthenticationToken authToken = token;
httpRequest = new HttpServletRequestWrapper(httpRequest) {
@Override
public String getAuthType() {
return authToken.getType();
}
@Override
public String getRemoteUser() {
return authToken.getUserName();
}
@Override
public Principal getUserPrincipal() {
return (authToken != AuthenticationToken.ANONYMOUS) ? authToken : null;
}
};
if ((newToken || allowTrustedProxy) && !token.isExpired() && token != AuthenticationToken.ANONYMOUS) {
String signedToken = signer.sign(token.toString());
createAuthCookie(httpResponse, signedToken, getCookieDomain(), getCookiePath(), token.getExpires(), isHttps);
}
doFilter(filterChain, httpRequest, httpResponse);
}
} else {
unauthorizedResponse = false;
}
} catch (AuthenticationException ex) {
// exception from the filter itself is fatal
ex.printStackTrace();
errCode = HttpServletResponse.SC_FORBIDDEN;
authenticationEx = ex;
LOG.warn("Authentication exception: {}", ex.getMessage(), ex);
}
if (unauthorizedResponse) {
String doAsUser = request.getParameter("doAs");
if (!httpResponse.isCommitted()) {
LOG.debug("create auth cookie");
createAuthCookie(httpResponse, "", getCookieDomain(), getCookiePath(), 0, isHttps);
// If response code is 401. Then WWW-Authenticate Header should be
// present.. reset to 403 if not found..
if ((errCode == HttpServletResponse.SC_UNAUTHORIZED) && (!httpResponse.containsHeader(KerberosAuthenticator.WWW_AUTHENTICATE) && !isKerberosEnabled && !supportKerberosAuthForBrowserLogin)) {
errCode = HttpServletResponse.SC_FORBIDDEN;
}
if (authenticationEx == null) {
String agents = PropertiesUtil.getProperty(BROWSER_USER_AGENT_PARAM, RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT);
if (agents == null) {
agents = RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT;
}
parseBrowserUserAgents(agents);
if (isBrowser(httpRequest.getHeader(RangerCSRFPreventionFilter.HEADER_USER_AGENT)) && (!allowTrustedProxy || StringUtils.isEmpty(doAsUser)) && !supportKerberosAuthForBrowserLogin) {
((HttpServletResponse) response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, "");
filterChain.doFilter(request, response);
} else {
if (isKerberosEnabled && isBrowser(httpRequest.getHeader(RangerCSRFPreventionFilter.HEADER_USER_AGENT)) && supportKerberosAuthForBrowserLogin) {
LOG.debug("Kerberos and ticket based browser login is enabled setting header to authenticate ticket based login for user.");
((HttpServletResponse) response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
}
if (allowTrustedProxy) {
String expectHeader = httpRequest.getHeader("Expect");
LOG.debug("expect header in request = {}", expectHeader);
LOG.debug("http response code = {}", httpResponse.getStatus());
if (expectHeader != null && expectHeader.startsWith("100")) {
LOG.debug("skipping 100 continue!!");
if (contentLength <= 0) {
contentLength = Integer.MAX_VALUE;
try {
LOG.debug("Skipping content length of {}", contentLength);
skipFully(request.getInputStream(), contentLength);
} catch (EOFException ex) {
LOG.info(ex.getMessage());
}
}
}
}
boolean chk = true;
Collection<String> headerNames = httpResponse.getHeaderNames();
LOG.debug("response header names = {}", headerNames);
for (String headerName : headerNames) {
String value = httpResponse.getHeader(headerName);
if ("Set-Cookie".equalsIgnoreCase(headerName) && value.startsWith(cookieName)) {
chk = false;
break;
}
}
String authHeader = httpRequest.getHeader("Authorization");
if (authHeader == null && chk) {
filterChain.doFilter(request, response);
} else if (authHeader != null && authHeader.startsWith("Basic")) {
filterChain.doFilter(request, response);
}
}
} else {
httpResponse.sendError(errCode, authenticationEx.getMessage());
}
}
}
}