use of org.ietf.jgss.GSSCredential in project hbase by apache.
the class TestSpnegoHttpServer method testAllowedClient.
@Test
public void testAllowedClient() throws Exception {
// Create the subject for the client
final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(CLIENT_PRINCIPAL, clientKeytab);
final Set<Principal> clientPrincipals = clientSubject.getPrincipals();
// Make sure the subject has a principal
assertFalse(clientPrincipals.isEmpty());
// Get a TGT for the subject (might have many, different encryption types). The first should
// be the default encryption type.
Set<KerberosTicket> privateCredentials = clientSubject.getPrivateCredentials(KerberosTicket.class);
assertFalse(privateCredentials.isEmpty());
KerberosTicket tgt = privateCredentials.iterator().next();
assertNotNull(tgt);
// The name of the principal
final String principalName = clientPrincipals.iterator().next().getName();
// Run this code, logged in as the subject (the client)
HttpResponse resp = Subject.doAs(clientSubject, new PrivilegedExceptionAction<HttpResponse>() {
@Override
public HttpResponse run() throws Exception {
// Logs in with Kerberos via GSS
GSSManager gssManager = GSSManager.getInstance();
// jGSS Kerberos login constant
Oid oid = new Oid("1.2.840.113554.1.2.2");
GSSName gssClient = gssManager.createName(principalName, GSSName.NT_USER_NAME);
GSSCredential credential = gssManager.createCredential(gssClient, GSSCredential.DEFAULT_LIFETIME, oid, GSSCredential.INITIATE_ONLY);
HttpClientContext context = HttpClientContext.create();
Lookup<AuthSchemeProvider> authRegistry = RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true, true)).build();
HttpClient client = HttpClients.custom().setDefaultAuthSchemeRegistry(authRegistry).build();
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new KerberosCredentials(credential));
URL url = new URL(getServerURL(server), "/echo?a=b");
context.setTargetHost(new HttpHost(url.getHost(), url.getPort()));
context.setCredentialsProvider(credentialsProvider);
context.setAuthSchemeRegistry(authRegistry);
HttpGet get = new HttpGet(url.toURI());
return client.execute(get, context);
}
});
assertNotNull(resp);
assertEquals(HttpURLConnection.HTTP_OK, resp.getStatusLine().getStatusCode());
assertEquals("a:b", EntityUtils.toString(resp.getEntity()).trim());
}
use of org.ietf.jgss.GSSCredential 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.GSSCredential in project drill by apache.
the class DrillSpnegoLoginService method spnegoLogin.
private UserIdentity spnegoLogin(Object credentials, ServletRequest request) {
String encodedAuthToken = (String) credentials;
byte[] authToken = B64Code.decode(encodedAuthToken);
GSSManager manager = GSSManager.getInstance();
try {
// Providing both OID's is required here. If we provide only one,
// we're requiring that clients provide us the SPNEGO OID to authenticate via Kerberos.
Oid[] knownOids = new Oid[2];
// spnego
knownOids[0] = new Oid("1.3.6.1.5.5.2");
// kerberos
knownOids[1] = new Oid("1.2.840.113554.1.2.2");
GSSName gssName = manager.createName(spnegoConfig.getSpnegoPrincipal(), null);
GSSCredential serverCreds = manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, knownOids, GSSCredential.ACCEPT_ONLY);
GSSContext gContext = manager.createContext(serverCreds);
if (gContext == null) {
logger.debug("SPNEGOUserRealm: failed to establish GSSContext");
} else {
while (!gContext.isEstablished()) {
authToken = gContext.acceptSecContext(authToken, 0, authToken.length);
}
if (gContext.isEstablished()) {
final String clientName = gContext.getSrcName().toString();
final String realm = clientName.substring(clientName.indexOf(64) + 1);
// Get the client user short name
final String userShortName = new HadoopKerberosName(clientName).getShortName();
logger.info("WebUser {} logged in from {}:{}", userShortName, request.getRemoteHost(), request.getRemotePort());
logger.debug("Client Name: {}, realm: {} and shortName: {}", clientName, realm, userShortName);
final SystemOptionManager sysOptions = drillContext.getOptionManager();
final boolean isAdmin = ImpersonationUtil.hasAdminPrivileges(userShortName, ExecConstants.ADMIN_USERS_VALIDATOR.getAdminUsers(sysOptions), ExecConstants.ADMIN_USER_GROUPS_VALIDATOR.getAdminUserGroups(sysOptions));
final Principal user = new DrillUserPrincipal(userShortName, isAdmin);
final Subject subject = new Subject();
subject.getPrincipals().add(user);
if (isAdmin) {
return this._identityService.newUserIdentity(subject, user, DrillUserPrincipal.ADMIN_USER_ROLES);
} else {
return this._identityService.newUserIdentity(subject, user, DrillUserPrincipal.NON_ADMIN_USER_ROLES);
}
}
}
} catch (GSSException gsse) {
logger.warn("Caught GSSException trying to authenticate the client", gsse);
} catch (IOException ex) {
logger.warn("Caught IOException trying to get shortName of client user", ex);
}
return null;
}
use of org.ietf.jgss.GSSCredential in project async-http-client by AsyncHttpClient.
the class SpnegoEngine method generateToken.
public String generateToken(String host) throws SpnegoEngineException {
GSSContext gssContext = null;
// base64 decoded challenge
byte[] token = null;
Oid negotiationOid;
try {
/*
* 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;
String spn = getCompleteServicePrincipalName(host);
try {
GSSManager manager = GSSManager.getInstance();
GSSName serverName = manager.createName(spn, GSSName.NT_HOSTBASED_SERVICE);
GSSCredential myCred = null;
if (username != null || loginContextName != null || (customLoginConfig != null && !customLoginConfig.isEmpty())) {
String contextName = loginContextName;
if (contextName == null) {
contextName = "";
}
LoginContext loginContext = new LoginContext(contextName, null, getUsernamePasswordHandler(), getLoginConfiguration());
loginContext.login();
final Oid negotiationOidFinal = negotiationOid;
final PrivilegedExceptionAction<GSSCredential> action = () -> manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, negotiationOidFinal, GSSCredential.INITIATE_AND_ACCEPT);
myCred = Subject.doAs(loginContext.getSubject(), action);
}
gssContext = manager.createContext(useCanonicalHostname ? serverName.canonicalize(negotiationOid) : serverName, negotiationOid, myCred, 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(spn, 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 | LoginException | PrivilegedActionException ex) {
throw new SpnegoEngineException(ex.getMessage());
}
}
use of org.ietf.jgss.GSSCredential in project keycloak by keycloak.
the class KerberosCredDelegServlet method doGet.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String ldapData = null;
if (req.getRequestURI().endsWith(CRED_DELEG_TEST_PATH)) {
try {
// Retrieve kerberos credential from accessToken and deserialize it
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) req.getUserPrincipal();
String serializedGssCredential = (String) keycloakPrincipal.getKeycloakSecurityContext().getToken().getOtherClaims().get(KerberosConstants.GSS_DELEGATION_CREDENTIAL);
GSSCredential gssCredential = KerberosSerializationUtils.deserializeCredential(serializedGssCredential);
// First try to invoke without gssCredential. It should fail
try {
invokeLdap(null);
throw new RuntimeException("Not expected to authenticate to LDAP without credential");
} catch (NamingException nse) {
System.out.println("Expected exception: " + nse.getMessage());
}
ldapData = invokeLdap(gssCredential);
} catch (KerberosSerializationUtils.KerberosSerializationException kse) {
System.err.println("KerberosSerializationUtils.KerberosSerializationException: " + kse.getMessage());
ldapData = "ERROR";
} catch (Exception e) {
e.printStackTrace();
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Kerberos Test");
pw.printf("Kerberos servlet secured content<br>");
if (ldapData != null) {
pw.printf("LDAP Data: " + ldapData + "<br>");
}
pw.print("</body></html>");
pw.flush();
}
Aggregations