From e1905e6961025ae93a5fc88892196df2e630181c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 19 Sep 2018 18:47:39 +0200 Subject: [PATCH] Issue #2868 - Adding SPNEGO authentication support for Jetty Client. Updates after review. Signed-off-by: Simone Bordet --- .../jetty/client/util/SPNEGOAuthentication.java | 1 - .../jetty/client/util/SPNEGOAuthenticationTest.java | 5 ++--- .../eclipse/jetty/security/SpnegoLoginService2.java | 2 +- .../eclipse/jetty/security/SpnegoUserIdentity.java | 10 +++++----- .../security/authentication/AuthorizationService.java | 9 +++++---- .../security/authentication/SpnegoAuthenticator2.java | 11 +++++++---- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java index ef96242c3e1..7fd33f988be 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java @@ -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); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java index 74875b9bcd9..906a36d751a 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java @@ -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()); } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java index 1e0567050ea..84c981a1817 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService2.java @@ -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 diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java index 4f191e8f337..307f4ba5e41 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java @@ -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; } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java index c2cb7ba1400..87adc2db830 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -26,24 +26,25 @@ import org.eclipse.jetty.server.UserIdentity; /** *

A service to query for user roles.

*/ +@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); /** *

Wraps a {@link LoginService} as an AuthorizationService

* * @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); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java index afc103ce643..5e8bb43e881 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator2.java @@ -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())