use of org.ietf.jgss.GSSContext in project async-http-client by AsyncHttpClient.
the class SpnegoEngine method generateToken.
public String generateToken(String server) throws SpnegoEngineException {
GSSContext gssContext = null;
// base64 decoded challenge
byte[] token = null;
Oid negotiationOid;
try {
log.debug("init {}", server);
/*
* Using the SPNEGO OID is the correct method. Kerberos v5 works for IIS but not JBoss. Unwrapping the initial token when using SPNEGO OID looks like what is described
* here...
*
* http://msdn.microsoft.com/en-us/library/ms995330.aspx
*
* Another helpful URL...
*
* http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html
*
* Unfortunately SPNEGO is JRE >=1.6.
*/
// Try SPNEGO by default, fall back to Kerberos later if error
negotiationOid = new Oid(SPNEGO_OID);
boolean tryKerberos = false;
try {
GSSManager manager = GSSManager.getInstance();
GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
gssContext = manager.createContext(serverName.canonicalize(negotiationOid), negotiationOid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(true);
gssContext.requestCredDeleg(true);
} catch (GSSException ex) {
log.error("generateToken", ex);
// Rethrow any other exception.
if (ex.getMajor() == GSSException.BAD_MECH) {
log.debug("GSSException BAD_MECH, retry with Kerberos MECH");
tryKerberos = true;
} else {
throw ex;
}
}
if (tryKerberos) {
/* Kerberos v5 GSS-API mechanism defined in RFC 1964. */
log.debug("Using Kerberos MECH {}", KERBEROS_OID);
negotiationOid = new Oid(KERBEROS_OID);
GSSManager manager = GSSManager.getInstance();
GSSName serverName = manager.createName("HTTP@" + server, GSSName.NT_HOSTBASED_SERVICE);
gssContext = manager.createContext(serverName.canonicalize(negotiationOid), negotiationOid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(true);
gssContext.requestCredDeleg(true);
}
// TODO suspicious: this will always be null because no value has been assigned before. Assign directly?
if (token == null) {
token = new byte[0];
}
token = gssContext.initSecContext(token, 0, token.length);
if (token == null) {
throw new SpnegoEngineException("GSS security context initialization failed");
}
/*
* IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish? seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token.
*/
if (spnegoGenerator != null && negotiationOid.toString().equals(KERBEROS_OID)) {
token = spnegoGenerator.generateSpnegoDERObject(token);
}
gssContext.dispose();
String tokenstr = Base64.getEncoder().encodeToString(token);
log.debug("Sending response '{}' back to the server", tokenstr);
return tokenstr;
} catch (GSSException gsse) {
log.error("generateToken", gsse);
if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED)
throw new SpnegoEngineException(gsse.getMessage(), gsse);
if (gsse.getMajor() == GSSException.NO_CRED)
throw new SpnegoEngineException(gsse.getMessage(), gsse);
if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN || gsse.getMajor() == GSSException.DUPLICATE_TOKEN || gsse.getMajor() == GSSException.OLD_TOKEN)
throw new SpnegoEngineException(gsse.getMessage(), gsse);
// other error
throw new SpnegoEngineException(gsse.getMessage());
} catch (IOException ex) {
throw new SpnegoEngineException(ex.getMessage());
}
}
use of org.ietf.jgss.GSSContext in project zeppelin by apache.
the class KerberosRealm method runWithPrincipal.
private AuthenticationToken runWithPrincipal(String serverPrincipal, byte[] clientToken, Base64 base64, HttpServletResponse response) throws IOException, GSSException {
GSSContext gssContext = null;
GSSCredential gssCreds = null;
AuthenticationToken token = null;
try {
LOG.trace("SPNEGO initiated with server principal [{}]", serverPrincipal);
gssCreds = this.gssManager.createCredential(this.gssManager.createName(serverPrincipal, KerberosUtil.NT_GSS_KRB5_PRINCIPAL_OID), GSSCredential.INDEFINITE_LIFETIME, new Oid[] { KerberosUtil.GSS_SPNEGO_MECH_OID, KerberosUtil.GSS_KRB5_MECH_OID }, GSSCredential.ACCEPT_ONLY);
gssContext = this.gssManager.createContext(gssCreds);
byte[] serverToken = gssContext.acceptSecContext(clientToken, 0, clientToken.length);
if (serverToken != null && serverToken.length > 0) {
String authenticate = base64.encodeToString(serverToken);
response.setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, 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, TYPE);
response.setStatus(HttpServletResponse.SC_OK);
LOG.trace("SPNEGO completed for client principal [{}]", clientPrincipal);
}
} finally {
if (gssContext != null) {
gssContext.dispose();
}
if (gssCreds != null) {
gssCreds.dispose();
}
}
return token;
}
use of org.ietf.jgss.GSSContext 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.ietf.jgss.GSSContext 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.ietf.jgss.GSSContext in project drill by apache.
the class TestDrillSpnegoAuthenticator method testSpnegoLoginInvalidToken.
/**
* Test to verify authentication fails when client sends invalid SPNEGO token for the
* {@link WebServerConstants#SPENGO_LOGIN_RESOURCE_PATH} resource.
*/
@Test
public void testSpnegoLoginInvalidToken() throws Exception {
final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
final HttpSession session = Mockito.mock(HttpSession.class);
// Create client subject using it's principal and keytab
final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(spnegoHelper.CLIENT_PRINCIPAL, spnegoHelper.clientKeytab.getAbsoluteFile());
// Generate a SPNEGO token for the peer SERVER_PRINCIPAL from this CLIENT_PRINCIPAL
final String token = Subject.doAs(clientSubject, (PrivilegedExceptionAction<String>) () -> {
final GSSManager gssManager = GSSManager.getInstance();
GSSContext gssContext = null;
try {
final Oid oid = GSSUtil.GSS_SPNEGO_MECH_OID;
final GSSName serviceName = gssManager.createName(spnegoHelper.SERVER_PRINCIPAL, GSSName.NT_USER_NAME, oid);
gssContext = gssManager.createContext(serviceName, oid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestCredDeleg(true);
gssContext.requestMutualAuth(true);
byte[] outToken = new byte[0];
outToken = gssContext.initSecContext(outToken, 0, outToken.length);
return Base64.encodeBase64String(outToken);
} finally {
if (gssContext != null) {
gssContext.dispose();
}
}
});
Mockito.when(request.getSession(true)).thenReturn(session);
final String httpReqAuthHeader = String.format("%s:%s", HttpHeader.NEGOTIATE.asString(), String.format("%s%s", "1234", token));
Mockito.when(request.getHeader(HttpHeader.AUTHORIZATION.asString())).thenReturn(httpReqAuthHeader);
Mockito.when(request.getRequestURI()).thenReturn(WebServerConstants.SPENGO_LOGIN_RESOURCE_PATH);
assertEquals(spnegoAuthenticator.validateRequest(request, response, false), Authentication.UNAUTHENTICATED);
verify(session, never()).setAttribute(SessionAuthentication.__J_AUTHENTICATED, null);
verify(response, never()).sendError(401);
verify(response, never()).setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString());
}
Aggregations