use of org.apache.hadoop.security.authentication.client.AuthenticationException in project incubator-atlas by apache.
the class AtlasAuthenticationFilter method getToken.
@Override
protected AuthenticationToken getToken(HttpServletRequest request) throws IOException, AuthenticationException {
AuthenticationToken token = null;
String tokenStr = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(AuthenticatedURL.AUTH_COOKIE)) {
tokenStr = cookie.getValue();
try {
tokenStr = this.signer.verifyAndExtract(tokenStr);
} catch (SignerException ex) {
throw new AuthenticationException(ex);
}
}
}
}
if (tokenStr != null) {
token = AuthenticationToken.parse(tokenStr);
if (token != null) {
AuthenticationHandler authHandler = getAuthenticationHandler();
if (!token.getType().equals(authHandler.getType())) {
throw new AuthenticationException("Invalid AuthenticationToken type");
}
if (token.isExpired()) {
throw new AuthenticationException("AuthenticationToken expired");
}
}
}
return token;
}
use of org.apache.hadoop.security.authentication.client.AuthenticationException in project druid by druid-io.
the class DruidKerberosAuthenticationHandler method authenticate.
@Override
public AuthenticationToken authenticate(HttpServletRequest request, final HttpServletResponse response) throws IOException, AuthenticationException {
AuthenticationToken token;
String authorization = request.getHeader(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.AUTHORIZATION);
if (authorization == null || !authorization.startsWith(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE)) {
return null;
} else {
authorization = authorization.substring(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE.length()).trim();
final byte[] clientToken = StringUtils.decodeBase64String(authorization);
final String serverName = request.getServerName();
try {
token = Subject.doAs(serverSubject, new PrivilegedExceptionAction<AuthenticationToken>() {
@Override
public AuthenticationToken run() throws Exception {
AuthenticationToken token = null;
GSSContext gssContext = null;
GSSCredential gssCreds = null;
try {
gssCreds = gssManager.createCredential(gssManager.createName(KerberosUtil.getServicePrincipal("HTTP", serverName), KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL")), GSSCredential.INDEFINITE_LIFETIME, new Oid[] { KerberosUtil.getOidInstance("GSS_SPNEGO_MECH_OID"), KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID") }, GSSCredential.ACCEPT_ONLY);
gssContext = gssManager.createContext(gssCreds);
byte[] serverToken = gssContext.acceptSecContext(clientToken, 0, clientToken.length);
if (serverToken != null && serverToken.length > 0) {
String authenticate = StringUtils.encodeBase64String(serverToken);
response.setHeader(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.WWW_AUTHENTICATE, org.apache.hadoop.security.authentication.client.KerberosAuthenticator.NEGOTIATE + " " + authenticate);
}
if (!gssContext.isEstablished()) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
log.trace("SPNEGO in progress");
} else {
String clientPrincipal = gssContext.getSrcName().toString();
KerberosName kerberosName = new KerberosName(clientPrincipal);
String userName = kerberosName.getShortName();
token = new AuthenticationToken(userName, clientPrincipal, getType());
response.setStatus(HttpServletResponse.SC_OK);
log.trace("SPNEGO completed for principal [%s]", clientPrincipal);
}
} finally {
if (gssContext != null) {
gssContext.dispose();
}
if (gssCreds != null) {
gssCreds.dispose();
}
}
return token;
}
});
} catch (PrivilegedActionException ex) {
if (ex.getException() instanceof IOException) {
throw (IOException) ex.getException();
} else {
throw new AuthenticationException(ex.getException());
}
}
}
return token;
}
use of org.apache.hadoop.security.authentication.client.AuthenticationException in project druid by druid-io.
the class KerberosAuthenticator method getFilter.
@Override
public Filter getFilter() {
return new AuthenticationFilter() {
private Signer mySigner;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try {
// AuthenticationHandler is created during Authenticationfilter.init using reflection with thread context class loader.
// In case of druid since the class is actually loaded as an extension and filter init is done in main thread.
// We need to set the classloader explicitly to extension class loader.
Thread.currentThread().setContextClassLoader(AuthenticationFilter.class.getClassLoader());
super.init(filterConfig);
String configPrefix = filterConfig.getInitParameter(CONFIG_PREFIX);
configPrefix = (configPrefix != null) ? configPrefix + "." : "";
Properties config = getConfiguration(configPrefix, filterConfig);
String signatureSecret = config.getProperty(configPrefix + SIGNATURE_SECRET);
if (signatureSecret == null) {
signatureSecret = Long.toString(ThreadLocalRandom.current().nextLong());
log.warn("'signature.secret' configuration not set, using a random value as secret");
}
final byte[] secretBytes = StringUtils.toUtf8(signatureSecret);
SignerSecretProvider signerSecretProvider = new SignerSecretProvider() {
@Override
public void init(Properties config, ServletContext servletContext, long tokenValidity) {
}
@Override
public byte[] getCurrentSecret() {
return secretBytes;
}
@Override
public byte[][] getAllSecrets() {
return new byte[][] { secretBytes };
}
};
mySigner = new Signer(signerSecretProvider);
} finally {
Thread.currentThread().setContextClassLoader(prevLoader);
}
}
// Copied from hadoop-auth's AuthenticationFilter, to allow us to change error response handling in doFilterSuper
@Override
protected AuthenticationToken getToken(HttpServletRequest request) throws AuthenticationException {
AuthenticationToken token = null;
String tokenStr = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(AuthenticatedURL.AUTH_COOKIE)) {
tokenStr = cookie.getValue();
try {
tokenStr = mySigner.verifyAndExtract(tokenStr);
} catch (SignerException ex) {
throw new AuthenticationException(ex);
}
break;
}
}
}
if (tokenStr != null) {
token = AuthenticationToken.parse(tokenStr);
if (!token.getType().equals(getAuthenticationHandler().getType())) {
throw new AuthenticationException("Invalid AuthenticationToken type");
}
if (token.isExpired()) {
throw new AuthenticationException("AuthenticationToken expired");
}
}
return token;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
// If there's already an auth result, then we have authenticated already, skip this.
if (request.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT) != null) {
filterChain.doFilter(request, response);
return;
}
// some other Authenticator didn't already validate this request.
if (loginContext == null) {
initializeKerberosLogin();
}
// Run the original doFilter method, but with modifications to error handling
doFilterSuper(request, response, filterChain);
}
/**
* Copied from hadoop-auth 2.7.3 AuthenticationFilter, to allow us to change error response handling.
* Specifically, we want to defer the sending of 401 Unauthorized so that other Authenticators later in the chain
* can check the request.
*/
private void doFilterSuper(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());
try {
boolean newToken = false;
AuthenticationToken token;
try {
token = getToken(httpRequest);
} catch (AuthenticationException ex) {
log.warn("AuthenticationToken ignored: " + ex.getMessage());
// will be sent back in a 401 unless filter authenticates
authenticationEx = ex;
token = null;
}
if (getAuthenticationHandler().managementOperation(token, httpRequest, httpResponse)) {
if (token == null) {
if (log.isDebugEnabled()) {
log.debug("Request [{%s}] triggering authentication", getRequestURL(httpRequest));
}
token = getAuthenticationHandler().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 [{%s}] user [{%s}] 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 && !token.isExpired() && token != AuthenticationToken.ANONYMOUS) {
String signedToken = mySigner.sign(token.toString());
tokenToAuthCookie(httpResponse, signedToken, getCookieDomain(), getCookiePath(), token.getExpires(), !token.isExpired() && token.getExpires() > 0, isHttps);
request.setAttribute(SIGNED_TOKEN_ATTRIBUTE, tokenToCookieString(signedToken, getCookieDomain(), getCookiePath(), token.getExpires(), !token.isExpired() && token.getExpires() > 0, isHttps));
}
// Since this request is validated also set DRUID_AUTHENTICATION_RESULT
request.setAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT, new AuthenticationResult(token.getName(), authorizerName, name, null));
doFilter(filterChain, httpRequest, httpResponse);
}
} else {
unauthorizedResponse = false;
}
} catch (AuthenticationException ex) {
// exception from the filter itself is fatal
errCode = HttpServletResponse.SC_FORBIDDEN;
authenticationEx = ex;
if (log.isDebugEnabled()) {
log.debug(ex, "Authentication exception: " + ex.getMessage());
} else {
log.warn("Authentication exception: " + ex.getMessage());
}
}
if (unauthorizedResponse) {
if (!httpResponse.isCommitted()) {
tokenToAuthCookie(httpResponse, "", getCookieDomain(), getCookiePath(), 0, false, isHttps);
// present.. reset to 403 if not found..
if ((errCode == HttpServletResponse.SC_UNAUTHORIZED) && (!httpResponse.containsHeader(org.apache.hadoop.security.authentication.client.KerberosAuthenticator.WWW_AUTHENTICATE))) {
errCode = HttpServletResponse.SC_FORBIDDEN;
}
if (authenticationEx == null) {
// Don't send an error response here, unlike the base AuthenticationFilter implementation.
// This request did not use Kerberos auth.
// Instead, we will send an error response in PreResponseAuthorizationCheckFilter to allow
// other Authenticator implementations to check the request.
filterChain.doFilter(request, response);
} else {
// Do send an error response here, we attempted Kerberos authentication and failed.
httpResponse.sendError(errCode, authenticationEx.getMessage());
}
}
}
}
};
}
use of org.apache.hadoop.security.authentication.client.AuthenticationException in project druid by druid-io.
the class DruidKerberosUtil method kerberosChallenge.
/**
* This method always needs to be called within a doAs block so that the client's TGT credentials
* can be read from the Subject.
*
* @return Kerberos Challenge String
*
* @throws Exception
*/
public static String kerberosChallenge(String server) throws AuthenticationException {
kerberosLock.lock();
try {
// This Oid for Kerberos GSS-API mechanism.
Oid mechOid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
GSSManager manager = GSSManager.getInstance();
// GSS name for server
GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
// Create a GSSContext for authentication with the service.
// We're passing client credentials as null since we want them to be read from the Subject.
GSSContext gssContext = manager.createContext(serverName.canonicalize(mechOid), mechOid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(true);
gssContext.requestCredDeleg(true);
// Establish context
byte[] inToken = new byte[0];
byte[] outToken = gssContext.initSecContext(inToken, 0, inToken.length);
gssContext.dispose();
// Base64 encoded and stringified token for server
return new String(StringUtils.encodeBase64(outToken), StandardCharsets.US_ASCII);
} catch (GSSException | IllegalAccessException | NoSuchFieldException | ClassNotFoundException e) {
throw new AuthenticationException(e);
} finally {
kerberosLock.unlock();
}
}
use of org.apache.hadoop.security.authentication.client.AuthenticationException in project ranger by apache.
the class RangerKrbFilter method doFilter.
/**
* If the request has a valid authentication token it allows the request to continue to the target resource,
* otherwise it triggers an authentication sequence using the configured {@link AuthenticationHandler}.
*
* @param request the request object.
* @param response the response object.
* @param filterChain the filter chain object.
*
* @throws IOException thrown if an IO error occurred.
* @throws ServletException thrown if a processing error occurred.
*/
@Override
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) {
if (!httpResponse.isCommitted()) {
if (LOG.isDebugEnabled()) {
LOG.debug("create auth cookie");
}
createAuthCookie(httpResponse, "", getCookieDomain(), getCookiePath(), 0, isHttps);
// present.. reset to 403 if not found..
if ((errCode == HttpServletResponse.SC_UNAUTHORIZED) && (!httpResponse.containsHeader(KerberosAuthenticator.WWW_AUTHENTICATE))) {
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);
String doAsUser = request.getParameter("doAs");
if (isBrowser(httpRequest.getHeader(RangerCSRFPreventionFilter.HEADER_USER_AGENT)) && (!allowTrustedProxy || (allowTrustedProxy && StringUtils.isEmpty(doAsUser)))) {
((HttpServletResponse) response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, "");
filterChain.doFilter(request, response);
} else {
if (allowTrustedProxy) {
String expectHeader = httpRequest.getHeader("Expect");
if (LOG.isDebugEnabled()) {
LOG.debug("expect header in request = " + expectHeader);
LOG.debug("http response code = " + httpResponse.getStatus());
}
if (expectHeader != null && expectHeader.startsWith("100")) {
if (LOG.isDebugEnabled()) {
LOG.debug("skipping 100 continue!!");
}
if (contentLength <= 0) {
Integer maxContentLen = Integer.MAX_VALUE;
contentLength = maxContentLen.longValue();
try {
if (LOG.isDebugEnabled()) {
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();
if (LOG.isDebugEnabled()) {
LOG.debug("reponse 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());
}
}
}
}
Aggregations