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);
|
return new DeferredAuthentication(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if we have authorization headers required to continue
|
// The client has responded to the challenge we sent previously
|
||||||
if ( header == null )
|
if (header != null && header.startsWith(HttpHeader.NEGOTIATE.asString().toLowerCase()))
|
||||||
{
|
|
||||||
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()))
|
|
||||||
{
|
{
|
||||||
String spnegoToken = header.substring(10);
|
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
|
@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