Issue #2868 - Adding SPNEGO authentication support for Jetty Client.

Updates after review.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2018-09-19 18:47:39 +02:00
parent f1391be559
commit e1905e6961
6 changed files with 20 additions and 18 deletions

View File

@ -171,7 +171,6 @@ public class SPNEGOAuthentication extends AbstractAuthentication
{
// First login via JAAS using the Kerberos AS_REQ call, with a client user.
// This will populate the Subject with the client user principal and the TGT.
// TODO: allow to use a keyTab.
String user = getUserName();
if (LOG.isDebugEnabled())
LOG.debug("Logging in user {}", user);

View File

@ -28,7 +28,6 @@ import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -124,7 +123,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
server = new Server();
server.setSessionIdManager(new DefaultSessionIdManager(server));
HashLoginService authorizationService = new HashLoginService(realm, realmPropsPath.toString());
SpnegoLoginService2 loginService = new SpnegoLoginService2(realm, AuthorizationService.from(authorizationService));
SpnegoLoginService2 loginService = new SpnegoLoginService2(realm, AuthorizationService.from(authorizationService, ""));
loginService.addBean(authorizationService);
loginService.setKeyTabPath(serviceKeyTabPath);
loginService.setServiceName(serviceName);
@ -222,7 +221,7 @@ public class SPNEGOAuthenticationTest extends AbstractHttpClientServerTest
startSPNEGO(scenario, new EmptyServerHandler()
{
@Override
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
{
IO.readBytes(request.getInputStream());
}

View File

@ -165,7 +165,7 @@ public class SpnegoLoginService2 extends ContainerLifeCycle implements LoginServ
if (httpSession != null)
httpSession.removeAttribute(GSSContextHolder.ATTRIBUTE);
UserIdentity roles = _authorizationService.getUserIdentity(request, userName, "");
UserIdentity roles = _authorizationService.getUserIdentity(request, userName);
return new SpnegoUserIdentity(subject, principal, roles);
}
else

View File

@ -28,13 +28,13 @@ public class SpnegoUserIdentity implements UserIdentity
{
private final Subject _subject;
private final Principal _principal;
private final UserIdentity _delegate;
private final UserIdentity _roleDelegate;
public SpnegoUserIdentity(Subject subject, Principal principal, UserIdentity delegate)
public SpnegoUserIdentity(Subject subject, Principal principal, UserIdentity roleDelegate)
{
_subject = subject;
_principal = principal;
_delegate = delegate;
_roleDelegate = roleDelegate;
}
@Override
@ -52,11 +52,11 @@ public class SpnegoUserIdentity implements UserIdentity
@Override
public boolean isUserInRole(String role, Scope scope)
{
return _delegate != null && _delegate.isUserInRole(role, scope);
return _roleDelegate != null && _roleDelegate.isUserInRole(role, scope);
}
public boolean isEstablished()
{
return _delegate != null;
return _roleDelegate != null;
}
}

View File

@ -26,24 +26,25 @@ import org.eclipse.jetty.server.UserIdentity;
/**
* <p>A service to query for user roles.</p>
*/
@FunctionalInterface
public interface AuthorizationService
{
/**
* @param request the current HTTP request
* @param name the user name
* @param credentials the user credentials
* @return a {@link UserIdentity} to query for roles of the given user
*/
UserIdentity getUserIdentity(HttpServletRequest request, String name, Object credentials);
UserIdentity getUserIdentity(HttpServletRequest request, String name);
/**
* <p>Wraps a {@link LoginService} as an AuthorizationService</p>
*
* @param loginService the {@link LoginService} to wrap
* @param credentials
* @return an AuthorizationService that delegates the query for roles to the given {@link LoginService}
*/
public static AuthorizationService from(LoginService loginService)
public static AuthorizationService from(LoginService loginService, Object credentials)
{
return (request, name, credentials) -> loginService.login(name, credentials, request);
return (request, name) -> loginService.login(name, credentials, request);
}
}

View File

@ -130,10 +130,13 @@ public class SpnegoAuthenticator2 extends LoginAuthenticator
{
if (identity.isEstablished())
{
if (LOG.isDebugEnabled())
LOG.debug("Sending final challenge");
SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
setSpnegoToken(response, principal.getEncodedToken());
if (!DeferredAuthentication.isDeferred(response))
{
if (LOG.isDebugEnabled())
LOG.debug("Sending final challenge");
SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal();
setSpnegoToken(response, principal.getEncodedToken());
}
Duration authnDuration = getAuthenticationDuration();
if (!authnDuration.isNegative())