private AuthenticationResult doAuthenticate()

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
                }
            }
        }
    }