use of org.ietf.jgss.GSSContext in project airlift by airlift.
the class SpnegoAuthentication method authenticate.
@Override
public Result authenticate(Request request, ContentResponse response, HeaderInfo headerInfo, Attributes attributes) {
URI normalizedUri = UriUtil.normalizedUri(request.getURI());
return new Result() {
@Override
public URI getURI() {
return normalizedUri;
}
@Override
public void apply(Request request) {
GSSContext context = null;
try {
String servicePrincipal = makeServicePrincipal(remoteServiceName, normalizedUri.getHost(), useCanonicalHostname);
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) {
request.header(headerInfo.getHeader(), format("%s %s", NEGOTIATE, Base64.getEncoder().encodeToString(token)));
} else {
throw new RuntimeException(format("No token generated from GSS context for %s", request.getURI()));
}
} catch (GSSException e) {
throw new RuntimeException(format("Failed to establish GSSContext for request %s", request.getURI()), e);
} catch (LoginException e) {
throw new RuntimeException(format("Failed to establish LoginContext for request %s", request.getURI()), e);
} finally {
try {
if (context != null) {
context.dispose();
}
} catch (GSSException e) {
// ignore
}
}
}
};
}
use of org.ietf.jgss.GSSContext in project registry by hortonworks.
the class TestKerberosAuthenticationHandler method testRequestWithAuthorization.
public void testRequestWithAuthorization() throws Exception {
String token = KerberosTestUtils.doAsClient(new Callable<String>() {
@Override
public String call() throws Exception {
GSSManager gssManager = GSSManager.getInstance();
GSSContext gssContext = null;
try {
String servicePrincipal = KerberosTestUtils.getServerPrincipal();
Oid oid = KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL");
GSSName serviceName = gssManager.createName(servicePrincipal, oid);
oid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
gssContext = gssManager.createContext(serviceName, oid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestCredDeleg(true);
gssContext.requestMutualAuth(true);
byte[] inToken = new byte[0];
byte[] outToken = gssContext.initSecContext(inToken, 0, inToken.length);
Base64 base64 = new Base64(0);
return base64.encodeToString(outToken);
} finally {
if (gssContext != null) {
gssContext.dispose();
}
}
}
});
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION)).thenReturn(KerberosAuthenticator.NEGOTIATE + " " + token);
Mockito.when(request.getServerName()).thenReturn("localhost");
AuthenticationToken authToken = handler.authenticate(request, response);
if (authToken != null) {
Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE), Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
Assert.assertEquals(KerberosTestUtils.getClientPrincipal(), authToken.getName());
Assert.assertTrue(KerberosTestUtils.getClientPrincipal().startsWith(authToken.getUserName()));
Assert.assertEquals(getExpectedType(), authToken.getType());
} else {
Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE), Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
use of org.ietf.jgss.GSSContext in project registry by hortonworks.
the class KerberosAuthenticator method doSpnegoSequence.
/**
* Implements the SPNEGO authentication sequence interaction using the current default principal
* in the Kerberos cache (normally set via kinit).
*
* @param token the authentication token being used for the user.
*
* @throws IOException if an IO error occurred.
* @throws AuthenticationException if an authentication error occurred.
*/
private void doSpnegoSequence(AuthenticatedURL.Token token) throws IOException, AuthenticationException {
try {
AccessControlContext context = AccessController.getContext();
Subject subject = Subject.getSubject(context);
if (subject == null || (subject.getPrivateCredentials(KerberosKey.class).isEmpty() && subject.getPrivateCredentials(KerberosTicket.class).isEmpty())) {
LOG.debug("No subject in context, logging in");
subject = new Subject();
LoginContext login = new LoginContext("", subject, null, new KerberosConfiguration());
login.login();
}
if (LOG.isDebugEnabled()) {
LOG.debug("Using subject: " + subject);
}
Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
GSSContext gssContext = null;
try {
GSSManager gssManager = GSSManager.getInstance();
String servicePrincipal = KerberosUtil.getServicePrincipal("HTTP", KerberosAuthenticator.this.url.getHost());
Oid oid = KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL");
GSSName serviceName = gssManager.createName(servicePrincipal, oid);
oid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
gssContext = gssManager.createContext(serviceName, oid, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestCredDeleg(true);
gssContext.requestMutualAuth(true);
byte[] inToken = new byte[0];
byte[] outToken;
boolean established = false;
// Loop while the context is still not established
while (!established) {
outToken = gssContext.initSecContext(inToken, 0, inToken.length);
if (outToken != null) {
sendToken(outToken);
}
if (!gssContext.isEstablished()) {
inToken = readToken();
} else {
established = true;
}
}
} finally {
if (gssContext != null) {
gssContext.dispose();
}
}
return null;
}
});
} catch (PrivilegedActionException ex) {
throw new AuthenticationException(ex.getException());
} catch (LoginException ex) {
throw new AuthenticationException(ex);
}
AuthenticatedURL.extractToken(conn, token);
}
use of org.ietf.jgss.GSSContext in project polymap4-core by Polymap4.
the class SpnegoAuthenticator method doSpnegoAuth.
/**
* Performs authentication using the SPNEGO mechanism.
*
* <p>
* Returns null if authentication failed or if the provided
* the auth scheme did not contain the SPNEGO/GSS token.
* </p>
*
* @return SpnegoPrincipal for the given auth scheme.
*/
private SpnegoPrincipal doSpnegoAuth(final SpnegoAuthScheme scheme, final SpnegoHttpServletResponse resp) throws GSSException, IOException {
final String principal;
final byte[] gss = scheme.getToken();
if (0 == gss.length) {
LOGGER.finer("GSS data was NULL.");
return null;
}
GSSContext context = null;
GSSCredential delegCred = null;
try {
byte[] token = null;
SpnegoAuthenticator.LOCK.lock();
try {
context = SpnegoAuthenticator.MANAGER.createContext(this.serverCredentials);
token = context.acceptSecContext(gss, 0, gss.length);
} finally {
SpnegoAuthenticator.LOCK.unlock();
}
if (null == token) {
LOGGER.finer("Token was NULL.");
return null;
}
resp.setHeader(Constants.AUTHN_HEADER, Constants.NEGOTIATE_HEADER + ' ' + Base64.encode(token));
if (!context.isEstablished()) {
LOGGER.fine("context not established");
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED, true);
return null;
}
principal = context.getSrcName().toString();
if (this.allowDelegation && context.getCredDelegState()) {
delegCred = context.getDelegCred();
}
} finally {
if (null != context) {
SpnegoAuthenticator.LOCK.lock();
try {
context.dispose();
} finally {
SpnegoAuthenticator.LOCK.unlock();
}
}
}
return new SpnegoPrincipal(principal, KerberosPrincipal.KRB_NT_PRINCIPAL, delegCred);
}
use of org.ietf.jgss.GSSContext in project polymap4-core by Polymap4.
the class SpnegoHttpURLConnection method connect.
/**
* Opens a communications link to the resource referenced by
* this URL, if such a connection has not already been established.
*
* @param url
* @param dooutput optional message/payload to send to server
* @return an HttpURLConnection object
* @throws GSSException
* @throws PrivilegedActionException
* @throws IOException
* @throws LoginException
*
* @see java.net.URLConnection#connect()
*/
public HttpURLConnection connect(final URL url, final ByteArrayOutputStream dooutput) throws GSSException, PrivilegedActionException, IOException {
assertNotConnected();
GSSContext context = null;
try {
byte[] data = null;
SpnegoHttpURLConnection.LOCK.lock();
try {
// work-around to GSSContext/AD timestamp vs sequence field replay bug
try {
Thread.sleep(31);
} catch (InterruptedException e) {
assert true;
}
context = this.getGSSContext(url);
context.requestMutualAuth(true);
context.requestConf(true);
context.requestInteg(true);
context.requestReplayDet(true);
context.requestSequenceDet(true);
context.requestCredDeleg(this.reqCredDeleg);
data = context.initSecContext(EMPTY_BYTE, 0, 0);
} finally {
SpnegoHttpURLConnection.LOCK.unlock();
}
this.conn = (HttpURLConnection) url.openConnection();
this.connected = true;
final Set<String> keys = this.requestProperties.keySet();
for (final String key : keys) {
for (String value : this.requestProperties.get(key)) {
this.conn.addRequestProperty(key, value);
}
}
// TODO : re-factor to support (302) redirects
this.conn.setInstanceFollowRedirects(false);
this.conn.setRequestMethod(this.requestMethod);
this.conn.setRequestProperty(Constants.AUTHZ_HEADER, Constants.NEGOTIATE_HEADER + ' ' + Base64.encode(data));
if (null != dooutput && dooutput.size() > 0) {
this.conn.setDoOutput(true);
dooutput.writeTo(this.conn.getOutputStream());
}
this.conn.connect();
final SpnegoAuthScheme scheme = SpnegoProvider.getAuthScheme(this.conn.getHeaderField(Constants.AUTHN_HEADER));
// app servers will not return a WWW-Authenticate on 302, (and 30x...?)
if (null == scheme) {
LOGGER.fine("SpnegoProvider.getAuthScheme(...) returned null.");
} else {
data = scheme.getToken();
if (Constants.NEGOTIATE_HEADER.equalsIgnoreCase(scheme.getScheme())) {
SpnegoHttpURLConnection.LOCK.lock();
try {
data = context.initSecContext(data, 0, data.length);
} finally {
SpnegoHttpURLConnection.LOCK.unlock();
}
// TODO : support context loops where i>1
if (null != data) {
LOGGER.warning("Server requested context loop: " + data.length);
}
} else {
throw new UnsupportedOperationException("Scheme NOT Supported: " + scheme.getScheme());
}
this.cntxtEstablished = context.isEstablished();
}
} finally {
this.dispose(context);
}
return this.conn;
}
Aggregations