Sends the WWW-Authenticate header if a non-Negotiate authorization he… (#1700)
* Sends the WWW-Authenticate header if a non-Negotiate authorization header was given Fixes #1698 Signed-off-by: Josh Elser <elserj@apache.org> * Dumb compilation error Signed-off-by: Josh Elser <elserj@apache.org> * Adds a test to show the challenge is sent. Signed-off-by: Josh Elser <elserj@apache.org> * Refactor the conditionals per Greg's suggestion Signed-off-by: Josh Elser <elserj@apache.org> * Add the expected license header Signed-off-by: Josh Elser <elserj@apache.org>
This commit is contained in:
parent
1a07ddd787
commit
1fd3e4ad1b
|
@ -72,27 +72,8 @@ public class SpnegoAuthenticator extends LoginAuthenticator
|
|||
return new DeferredAuthentication(this);
|
||||
}
|
||||
|
||||
// check to see if we have authorization headers required to continue
|
||||
if ( header == null )
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DeferredAuthentication.isDeferred(res))
|
||||
{
|
||||
return Authentication.UNAUTHENTICATED;
|
||||
}
|
||||
|
||||
LOG.debug("SpengoAuthenticator: sending challenge");
|
||||
res.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString());
|
||||
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return Authentication.SEND_CONTINUE;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new ServerAuthException(ioe);
|
||||
}
|
||||
}
|
||||
else if (header != null && header.startsWith(HttpHeader.NEGOTIATE.asString()))
|
||||
// The client has responded to the challenge we sent previously
|
||||
if (header != null && header.startsWith(HttpHeader.NEGOTIATE.asString().toLowerCase()))
|
||||
{
|
||||
String spnegoToken = header.substring(10);
|
||||
|
||||
|
@ -104,7 +85,25 @@ public class SpnegoAuthenticator extends LoginAuthenticator
|
|||
}
|
||||
}
|
||||
|
||||
return Authentication.UNAUTHENTICATED;
|
||||
// A challenge should be sent if any of the following cases are true:
|
||||
// 1. There was no Authorization header provided
|
||||
// 2. There was an Authorization header for a type other than Negotiate
|
||||
try
|
||||
{
|
||||
if (DeferredAuthentication.isDeferred(res))
|
||||
{
|
||||
return Authentication.UNAUTHENTICATED;
|
||||
}
|
||||
|
||||
LOG.debug("SpengoAuthenticator: sending challenge");
|
||||
res.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString());
|
||||
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return Authentication.SEND_CONTINUE;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new ServerAuthException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.security.authentication;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.server.Authentication;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpOutput;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test class for {@link SpnegoAuthenticator}.
|
||||
*/
|
||||
public class SpnegoAuthenticatorTest {
|
||||
private SpnegoAuthenticator _authenticator;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception
|
||||
{
|
||||
_authenticator = new SpnegoAuthenticator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChallengeSentWithNoAuthorization() throws Exception
|
||||
{
|
||||
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public Server getServer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Request req = new Request(channel, null);
|
||||
HttpOutput out = new HttpOutput(channel)
|
||||
{
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
Response res = new Response(channel, out);
|
||||
MetaData.Request metadata = new MetaData.Request(new HttpFields());
|
||||
metadata.setURI(new HttpURI("http://localhost"));
|
||||
req.setMetaData(metadata);
|
||||
|
||||
assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true));
|
||||
assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString()));
|
||||
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChallengeSentWithUnhandledAuthorization() throws Exception
|
||||
{
|
||||
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public Server getServer()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Request req = new Request(channel, null);
|
||||
HttpOutput out = new HttpOutput(channel)
|
||||
{
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
Response res = new Response(channel, out);
|
||||
HttpFields http_fields = new HttpFields();
|
||||
// Create a bogus Authorization header. We don't care about the actual credentials.
|
||||
http_fields.add(HttpHeader.AUTHORIZATION, "Basic asdf");
|
||||
MetaData.Request metadata = new MetaData.Request(http_fields);
|
||||
metadata.setURI(new HttpURI("http://localhost"));
|
||||
req.setMetaData(metadata);
|
||||
|
||||
assertEquals(Authentication.SEND_CONTINUE, _authenticator.validateRequest(req, res, true));
|
||||
assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString()));
|
||||
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue