use of org.ietf.jgss.GSSCredential in project zookeeper by apache.
the class SecurityUtils method createSaslClient.
/**
* Create an instance of a SaslClient. It will return null if there is an exception.
*
* @param subject subject
* @param servicePrincipal principal
* @param protocol name of the protocol for which the authentication is being performed
* @param serverName name of the server to authenticate to
* @param LOG logger
* @param entity can be either zookeeper client or quorum learner
*
* @return saslclient object
* @throws SaslException
*/
public static SaslClient createSaslClient(final Subject subject, final String servicePrincipal, final String protocol, final String serverName, final Logger LOG, final String entity) throws SaslException {
SaslClient saslClient;
// mechanism to use: if empty, use DIGEST-MD5; otherwise, use GSSAPI.
if (subject.getPrincipals().isEmpty()) {
// no principals: must not be GSSAPI: use DIGEST-MD5 mechanism
// instead.
LOG.info("{} will use DIGEST-MD5 as SASL mechanism.", entity);
String[] mechs = { "DIGEST-MD5" };
String username = (String) (subject.getPublicCredentials().toArray()[0]);
String password = (String) (subject.getPrivateCredentials().toArray()[0]);
// 'domain' parameter is hard-wired between the server and client
saslClient = Sasl.createSaslClient(mechs, username, protocol, serverName, null, new SaslClientCallbackHandler(password, entity));
return saslClient;
} else {
// GSSAPI.
final Object[] principals = subject.getPrincipals().toArray();
// determine client principal from subject.
final Principal clientPrincipal = (Principal) principals[0];
boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
if (usingNativeJgss) {
// """
try {
GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSCredential cred = manager.createCredential(null, GSSContext.DEFAULT_LIFETIME, krb5Mechanism, GSSCredential.INITIATE_ONLY);
subject.getPrivateCredentials().add(cred);
LOG.debug("Added private credential to {} principal name: '{}'", entity, clientPrincipal);
} catch (GSSException ex) {
LOG.warn("Cannot add private credential to subject; authentication at the server may fail", ex);
}
}
final KerberosName clientKerberosName = new KerberosName(clientPrincipal.getName());
// assume that server and client are in the same realm (by default;
// unless the system property
// "zookeeper.server.realm" is set).
String serverRealm = System.getProperty("zookeeper.server.realm", clientKerberosName.getRealm());
String modifiedServerPrincipal = servicePrincipal;
// If service principal does not contain realm, then add it
if (!modifiedServerPrincipal.contains("@")) {
modifiedServerPrincipal = modifiedServerPrincipal + "@" + serverRealm;
}
KerberosName serviceKerberosName = new KerberosName(modifiedServerPrincipal);
final String serviceName = serviceKerberosName.getServiceName();
final String serviceHostname = serviceKerberosName.getHostName();
final String clientPrincipalName = clientKerberosName.toString();
try {
saslClient = Subject.doAs(subject, new PrivilegedExceptionAction<SaslClient>() {
public SaslClient run() throws SaslException {
LOG.info("{} will use GSSAPI as SASL mechanism.", entity);
String[] mechs = { "GSSAPI" };
LOG.debug("creating sasl client: {}={};service={};serviceHostname={}", entity, clientPrincipalName, serviceName, serviceHostname);
SaslClient saslClient = Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null, new SaslClientCallbackHandler(null, entity));
return saslClient;
}
});
return saslClient;
} catch (Exception e) {
LOG.error("Exception while trying to create SASL client", e);
return null;
}
}
}
use of org.ietf.jgss.GSSCredential in project zookeeper by apache.
the class SecurityUtils method createSaslServer.
/**
* Create an instance of a SaslServer. It will return null if there is an exception.
*
* @param subject subject
* @param protocol protocol
* @param serverName server name
* @param callbackHandler login callback handler
* @param LOG logger
* @return sasl server object
*/
public static SaslServer createSaslServer(final Subject subject, final String protocol, final String serverName, final CallbackHandler callbackHandler, final Logger LOG) {
if (subject != null) {
// principal name and hostname from zk server's subject.
if (subject.getPrincipals().size() > 0) {
try {
final Object[] principals = subject.getPrincipals().toArray();
final Principal servicePrincipal = (Principal) principals[0];
// e.g. servicePrincipalNameAndHostname :=
// "zookeeper/myhost.foo.com@FOO.COM"
final String servicePrincipalNameAndHostname = servicePrincipal.getName();
int indexOf = servicePrincipalNameAndHostname.indexOf("/");
// e.g. servicePrincipalName := "zookeeper"
final String servicePrincipalName = servicePrincipalNameAndHostname.substring(0, indexOf);
// e.g. serviceHostnameAndKerbDomain :=
// "myhost.foo.com@FOO.COM"
final String serviceHostnameAndKerbDomain = servicePrincipalNameAndHostname.substring(indexOf + 1);
indexOf = serviceHostnameAndKerbDomain.indexOf("@");
// e.g. serviceHostname := "myhost.foo.com"
final String serviceHostname = serviceHostnameAndKerbDomain.substring(0, indexOf);
// TODO: should depend on zoo.cfg specified mechs, but if
// subject is non-null, it can be assumed to be GSSAPI.
final String mech = "GSSAPI";
LOG.debug("serviceHostname is '{}'", serviceHostname);
LOG.debug("servicePrincipalName is '{}'", servicePrincipalName);
LOG.debug("SASL mechanism(mech) is '{}'", mech);
boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
if (usingNativeJgss) {
// """
try {
GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSName gssName = manager.createName(servicePrincipalName + "@" + serviceHostname, GSSName.NT_HOSTBASED_SERVICE);
GSSCredential cred = manager.createCredential(gssName, GSSContext.DEFAULT_LIFETIME, krb5Mechanism, GSSCredential.ACCEPT_ONLY);
subject.getPrivateCredentials().add(cred);
LOG.debug("Added private credential to service principal name: '{}', GSSCredential name: {}", servicePrincipalName, cred.getName());
} catch (GSSException ex) {
LOG.warn("Cannot add private credential to subject; clients authentication may fail", ex);
}
}
try {
return Subject.doAs(subject, new PrivilegedExceptionAction<SaslServer>() {
public SaslServer run() {
try {
SaslServer saslServer;
saslServer = Sasl.createSaslServer(mech, servicePrincipalName, serviceHostname, null, callbackHandler);
return saslServer;
} catch (SaslException e) {
LOG.error("Zookeeper Server failed to create a SaslServer to interact with a client during session initiation", e);
return null;
}
}
});
} catch (PrivilegedActionException e) {
// TODO: exit server at this point(?)
LOG.error("Zookeeper Quorum member experienced a PrivilegedActionException exception while creating a SaslServer using a JAAS principal context", e);
}
} catch (IndexOutOfBoundsException e) {
LOG.error("server principal name/hostname determination error", e);
}
} else {
// TODO: use 'authMech=' value in zoo.cfg.
try {
SaslServer saslServer = Sasl.createSaslServer("DIGEST-MD5", protocol, serverName, null, callbackHandler);
return saslServer;
} catch (SaslException e) {
LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation", e);
}
}
}
return null;
}
use of org.ietf.jgss.GSSCredential in project tomcat by apache.
the class SpnegoAuthenticator method doAuthenticate.
@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) 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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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 = () -> 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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_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.GSSCredential in project ranger by apache.
the class CredentialsProviderUtil method getKerberosCredentials.
public static KerberosCredentialsProvider getKerberosCredentials(String user, String password) {
KerberosCredentialsProvider credentialsProvider = new KerberosCredentialsProvider();
final GSSManager gssManager = GSSManager.getInstance();
try {
final GSSName gssUserPrincipalName = gssManager.createName(user, GSSName.NT_USER_NAME);
Subject subject = login(user, password);
final AccessControlContext acc = AccessController.getContext();
final GSSCredential credential = doAsPrivilegedWrapper(subject, (PrivilegedExceptionAction<GSSCredential>) () -> gssManager.createCredential(gssUserPrincipalName, GSSCredential.DEFAULT_LIFETIME, SPNEGO_OID, GSSCredential.INITIATE_ONLY), acc);
credentialsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO), new KerberosCredentials(credential));
} catch (GSSException e) {
logger.error("GSSException:", e);
throw new RuntimeException(e);
} catch (PrivilegedActionException e) {
logger.error("PrivilegedActionException:", e);
throw new RuntimeException(e);
}
return credentialsProvider;
}
use of org.ietf.jgss.GSSCredential in project knox by apache.
the class SpnegoAuthInterceptor method createCredentialSession.
private GSSCredentialSession createCredentialSession() throws GSSException {
Principal clientPrincipal = subject.getPrincipals().iterator().next();
GSSCredential clientCredential = doAs(subject, () -> GSS_MANAGER.createCredential(GSS_MANAGER.createName(clientPrincipal.getName(), NT_USER_NAME), DEFAULT_LIFETIME, KERBEROS_OID, INITIATE_ONLY));
return new GSSCredentialSession(clientCredential);
}
Aggregations