use of org.ietf.jgss.GSSContext in project tomcat70 by apache.
the class SpnegoAuthenticator method authenticate.
@Override
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
if (checkForCachedAuthentication(request, response, true)) {
return true;
}
MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");
if (authorization == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("authenticator.noAuthHeader"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
authorization.toBytes();
ByteChunk authorizationBC = authorization.getByteChunk();
if (!authorizationBC.startsWithIgnoreCase("negotiate ", 0)) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.authHeaderNotNego"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
authorizationBC.setOffset(authorizationBC.getOffset() + 10);
byte[] decoded = Base64.decodeBase64(authorizationBC.getBuffer(), authorizationBC.getOffset(), authorizationBC.getLength());
if (getApplyJava8u40Fix()) {
SpnegoTokenFixer.fix(decoded);
}
if (decoded.length == 0) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.authHeaderNoToken"));
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
LoginContext lc = null;
GSSContext gssContext = null;
byte[] outToken = null;
Principal principal = null;
try {
try {
lc = new LoginContext(getLoginConfigName());
lc.login();
} catch (LoginException e) {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return false;
}
Subject subject = lc.getSubject();
// Assume the GSSContext is stateless
// TODO: Confirm this assumption
final GSSManager manager = GSSManager.getInstance();
// IBM JDK only understands indefinite lifetime
final int credentialLifetime;
if (JreVendor.IS_IBM_JVM) {
credentialLifetime = GSSCredential.INDEFINITE_LIFETIME;
} else {
credentialLifetime = GSSCredential.DEFAULT_LIFETIME;
}
final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
@Override
public GSSCredential run() throws GSSException {
return manager.createCredential(null, credentialLifetime, new Oid("1.3.6.1.5.5.2"), GSSCredential.ACCEPT_ONLY);
}
};
gssContext = manager.createContext(Subject.doAs(subject, action));
outToken = Subject.doAs(lc.getSubject(), new AcceptAction(gssContext, decoded));
if (outToken == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"));
}
// Start again
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
principal = Subject.doAs(subject, new AuthenticateAction(context.getRealm(), gssContext, storeDelegatedCredential));
} catch (GSSException e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"), e);
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
} catch (PrivilegedActionException e) {
Throwable cause = e.getCause();
if (cause instanceof GSSException) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
}
} else {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
} finally {
if (gssContext != null) {
try {
gssContext.dispose();
} catch (GSSException e) {
// Ignore
}
}
if (lc != null) {
try {
lc.logout();
} catch (LoginException e) {
// Ignore
}
}
}
// Send response token on success and failure
response.setHeader("WWW-Authenticate", "Negotiate " + Base64.encodeBase64String(outToken));
if (principal != null) {
register(request, response, principal, Constants.SPNEGO_METHOD, principal.getName(), null);
Pattern p = noKeepAliveUserAgents;
if (p != null) {
MessageBytes ua = request.getCoyoteRequest().getMimeHeaders().getValue("user-agent");
if (ua != null && p.matcher(ua.toString()).matches()) {
response.setHeader("Connection", "close");
}
}
return true;
}
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
use of org.ietf.jgss.GSSContext in project registry by hortonworks.
the class KerberosAuthenticationHandler method authenticate.
/**
* It enforces the the Kerberos SPNEGO authentication sequence returning an {@link AuthenticationToken} only
* after the Kerberos SPNEGO sequence has completed successfully.
*
* @param request the HTTP client request.
* @param response the HTTP client response.
*
* @return an authentication token if the Kerberos SPNEGO sequence is complete and valid,
* <code>null</code> if it is in progress (in this case the handler handles the response to the client).
*
* @throws IOException thrown if an IO error occurred.
* @throws AuthenticationException thrown if Kerberos SPNEGO sequence failed.
*/
@Override
public AuthenticationToken authenticate(HttpServletRequest request, final HttpServletResponse response) throws IOException, AuthenticationException {
AuthenticationToken token = null;
String authorization = request.getHeader(KerberosAuthenticator.AUTHORIZATION);
if (authorization == null || !authorization.startsWith(KerberosAuthenticator.NEGOTIATE)) {
response.setHeader(WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
if (authorization == null) {
LOG.trace("SPNEGO starting");
} else {
LOG.warn("'" + KerberosAuthenticator.AUTHORIZATION + "' does not start with '" + KerberosAuthenticator.NEGOTIATE + "' : {}", authorization);
}
} else {
authorization = authorization.substring(KerberosAuthenticator.NEGOTIATE.length()).trim();
final byte[] clientToken = Base64.getDecoder().decode(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 = Base64.getEncoder().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, getType());
response.setStatus(HttpServletResponse.SC_OK);
LOG.trace("SPNEGO completed for principal [{}]", 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 drill by apache.
the class TestSpnegoAuthentication method testDrillSpnegoLoginService.
/**
* Validate successful {@link DrillSpnegoLoginService#login(String, Object, javax.servlet.ServletRequest)}
* when provided with client token for a configured service principal.
*/
@Test
public void testDrillSpnegoLoginService() throws Exception {
// 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, new PrivilegedExceptionAction<String>() {
@Override
public String run() throws Exception {
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();
}
}
}
});
// Create a DrillbitContext with service principal and keytab for DrillSpnegoLoginService
final DrillConfig newConfig = new DrillConfig(DrillConfig.create().withValue(ExecConstants.HTTP_AUTHENTICATION_MECHANISMS, ConfigValueFactory.fromIterable(Lists.newArrayList("spnego"))).withValue(ExecConstants.HTTP_SPNEGO_PRINCIPAL, ConfigValueFactory.fromAnyRef(spnegoHelper.SERVER_PRINCIPAL)).withValue(ExecConstants.HTTP_SPNEGO_KEYTAB, ConfigValueFactory.fromAnyRef(spnegoHelper.serverKeytab.toString())));
final SystemOptionManager optionManager = Mockito.mock(SystemOptionManager.class);
Mockito.when(optionManager.getOption(ExecConstants.ADMIN_USERS_VALIDATOR)).thenReturn(ExecConstants.ADMIN_USERS_VALIDATOR.DEFAULT_ADMIN_USERS);
Mockito.when(optionManager.getOption(ExecConstants.ADMIN_USER_GROUPS_VALIDATOR)).thenReturn(ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.DEFAULT_ADMIN_USER_GROUPS);
final DrillbitContext drillbitContext = Mockito.mock(DrillbitContext.class);
Mockito.when(drillbitContext.getConfig()).thenReturn(newConfig);
Mockito.when(drillbitContext.getOptionManager()).thenReturn(optionManager);
final DrillSpnegoLoginService loginService = new DrillSpnegoLoginService(drillbitContext);
// Authenticate the client using its SPNEGO token
final UserIdentity user = loginService.login(null, token, null);
// Validate the UserIdentity of authenticated client
assertNotNull(user);
assertEquals(user.getUserPrincipal().getName(), spnegoHelper.CLIENT_SHORT_NAME);
assertTrue(user.isUserInRole("authenticated", null));
}
use of org.ietf.jgss.GSSContext in project presto by prestodb.
the class SpnegoHandler method generateToken.
private byte[] generateToken(String servicePrincipal) {
GSSContext context = null;
try {
Session session = getSession();
context = doAs(session.getLoginContext().getSubject(), () -> {
GSSContext result = GSS_MANAGER.createContext(GSS_MANAGER.createName(servicePrincipal, NT_HOSTBASED_SERVICE), SPNEGO_OID, session.getClientCredential(), INDEFINITE_LIFETIME);
result.requestMutualAuth(true);
result.requestConf(true);
result.requestInteg(true);
result.requestCredDeleg(false);
return result;
});
byte[] token = context.initSecContext(new byte[0], 0, 0);
if (token == null) {
throw new LoginException("No token generated from GSS context");
}
return token;
} catch (GSSException | LoginException e) {
throw new ClientException(format("Kerberos error for [%s]: %s", servicePrincipal, e.getMessage()), e);
} finally {
try {
if (context != null) {
context.dispose();
}
} catch (GSSException ignored) {
}
}
}
use of org.ietf.jgss.GSSContext in project hbase by apache.
the class HttpDoAsClient method generateTicket.
private String generateTicket() throws GSSException {
final GSSManager manager = GSSManager.getInstance();
// Oid for kerberos principal name
Oid krb5PrincipalOid = new Oid("1.2.840.113554.1.2.2.1");
Oid KERB_V5_OID = new Oid("1.2.840.113554.1.2.2");
final GSSName clientName = manager.createName(principal, krb5PrincipalOid);
final GSSCredential clientCred = manager.createCredential(clientName, 8 * 3600, KERB_V5_OID, GSSCredential.INITIATE_ONLY);
final GSSName serverName = manager.createName(principal, krb5PrincipalOid);
final GSSContext context = manager.createContext(serverName, KERB_V5_OID, clientCred, GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true);
context.requestConf(false);
context.requestInteg(true);
final byte[] outToken = context.initSecContext(new byte[0], 0, 0);
StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append("Negotiate ");
outputBuffer.append(Bytes.toString(Base64.getEncoder().encode(outToken)));
System.out.print("Ticket is: " + outputBuffer);
return outputBuffer.toString();
}
Aggregations