in broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SpnegoAuthenticator.java [156:319]
private AuthenticationResult doAuthenticate(final Subject subject, final byte[] negotiateToken)
{
GSSContext context = null;
try
{
final int credentialLifetime;
if (String.valueOf(System.getProperty(SystemProperties.JAVA_VENDOR))
.toUpperCase()
.contains("IBM"))
{
credentialLifetime = GSSCredential.INDEFINITE_LIFETIME;
}
else
{
credentialLifetime = GSSCredential.DEFAULT_LIFETIME;
}
final GSSManager manager = GSSManager.getInstance();
final PrivilegedExceptionAction<GSSCredential> credentialsAction =
() -> manager.createCredential(null,
credentialLifetime,
new Oid("1.3.6.1.5.5.2"),
GSSCredential.ACCEPT_ONLY);
final GSSContext gssContext = manager.createContext(Subject.doAs(subject, credentialsAction));
context = gssContext;
final PrivilegedExceptionAction<byte[]> acceptAction =
() -> gssContext.acceptSecContext(negotiateToken, 0, negotiateToken.length);
final byte[] outToken = Subject.doAs(subject, acceptAction);
if (outToken == null)
{
LOGGER.debug("Ticket validation failed");
return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
}
final PrivilegedAction<String> authenticationAction = () -> {
if (gssContext.isEstablished())
{
GSSName gssName = null;
try
{
gssName = gssContext.getSrcName();
}
catch (final GSSException e)
{
LOGGER.error("Unable to get src name from gss context", e);
}
if (gssName != null)
{
return stripRealmNameIfRequired(gssName.toString());
}
}
return null;
};
final String principalName = Subject.doAs(subject, authenticationAction);
if (principalName != null)
{
TokenCarryingPrincipal principal = new TokenCarryingPrincipal()
{
private final Map<String, String> _tokens = Collections.singletonMap(RESPONSE_AUTH_HEADER_NAME,
NEGOTIATE_PREFIX + Base64.getEncoder()
.encodeToString(outToken));
@Override
public Map<String, String> getTokens()
{
return _tokens;
}
@Override
public ConfiguredObject<?> getOrigin()
{
return _kerberosProvider;
}
@Override
public String getName()
{
return principalName;
}
@Override
public boolean equals(final Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof TokenCarryingPrincipal))
{
return false;
}
final TokenCarryingPrincipal that = (TokenCarryingPrincipal) o;
if (!getName().equals(that.getName()))
{
return false;
}
if (!getTokens().equals(that.getTokens()))
{
return false;
}
return getOrigin() != null ? getOrigin().equals(that.getOrigin()) : that.getOrigin() == null;
}
@Override
public int hashCode()
{
int result = getName().hashCode();
result = 31 * result + (getOrigin() != null ? getOrigin().hashCode() : 0);
result = 31 * result + getTokens().hashCode();
return result;
}
};
return new AuthenticationResult(principal);
}
return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
}
catch (GSSException e)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Ticket validation failed", e);
}
return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
}
catch (PrivilegedActionException e)
{
final Exception cause = e.getException();
if (cause instanceof GSSException)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Service login failed", e);
}
}
else
{
LOGGER.error("Service login failed", e);
}
return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
}
finally
{
if (context != null)
{
try
{
context.dispose();
}
catch (GSSException e)
{
// Ignore
}
}
}
}