diff --git a/cadc-access-control-server/build.gradle b/cadc-access-control-server/build.gradle index 8d4b6b5cce53cffb2790aebe655b810472c8a6bb..53822b1989eaa92eadd3e5cc561db47ee37d9782 100644 --- a/cadc-access-control-server/build.gradle +++ b/cadc-access-control-server/build.gradle @@ -13,7 +13,7 @@ repositories { sourceCompatibility = 1.7 group = 'org.opencadc' -version = '1.1.2' +version = '1.1.3' dependencies { compile 'log4j:log4j:1.2.+' diff --git a/cadc-access-control-server/src/main/java/ca/nrc/cadc/ac/server/web/WhoAmIServlet.java b/cadc-access-control-server/src/main/java/ca/nrc/cadc/ac/server/web/WhoAmIServlet.java index a497866059e4451c799fc2125bb2b20ed4abce76..13db215b335f13013481288bee705687ad97ffda 100644 --- a/cadc-access-control-server/src/main/java/ca/nrc/cadc/ac/server/web/WhoAmIServlet.java +++ b/cadc-access-control-server/src/main/java/ca/nrc/cadc/ac/server/web/WhoAmIServlet.java @@ -71,9 +71,10 @@ package ca.nrc.cadc.ac.server.web; import java.io.IOException; import java.net.URI; import java.net.URL; -import java.util.Set; +import java.security.Principal; import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -84,6 +85,7 @@ import org.apache.log4j.Logger; import ca.nrc.cadc.auth.AuthMethod; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.log.ServletLogInfo; import ca.nrc.cadc.reg.Standards; import ca.nrc.cadc.reg.client.LocalAuthority; @@ -99,7 +101,7 @@ public class WhoAmIServlet extends HttpServlet { private static final Logger log = Logger.getLogger(WhoAmIServlet.class); - static final String USER_GET_PATH = "/%s?idType=HTTP"; + static final String USER_GET_PATH = "/%s?idType=%s"; /** * Handle a /whoami GET operation. @@ -119,19 +121,23 @@ public class WhoAmIServlet extends HttpServlet log.info(logInfo.start()); try { - final Subject currentSubject = getSubject(request); - final Set<HttpPrincipal> currentWebPrincipals = - currentSubject.getPrincipals(HttpPrincipal.class); - - if (currentWebPrincipals.isEmpty()) + final Subject subject = getSubject(request); + AuthMethod authMethod = getAuthMethod(subject); + if (AuthMethod.ANON.equals(authMethod)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; } - else + + Principal principal = getPrincipalForRestCall(subject); + if (principal == null) { - redirect(response, currentWebPrincipals.toArray( - new HttpPrincipal[1])[0], request.getScheme()); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + response.getWriter().print("No supported identities for /whoami"); + return; } + + redirect(response, principal, authMethod); } catch (IllegalArgumentException e) { @@ -154,12 +160,37 @@ public class WhoAmIServlet extends HttpServlet } } + private Principal getPrincipalForRestCall(Subject s) + { + // TODO: Would be better to add this type of checking to AuthenticationUtil. + // But: a better fix would probably be to remove the userid and + // authentication type from the get user REST call. Only the + // calling user is allowed to get that user, so the information + // is already available. + + if (!s.getPrincipals(HttpPrincipal.class).isEmpty()) + return s.getPrincipals(HttpPrincipal.class).iterator().next(); + + if (!s.getPrincipals(X500Principal.class).isEmpty()) + return s.getPrincipals(X500Principal.class).iterator().next(); + + if (!s.getPrincipals(NumericPrincipal.class).isEmpty()) + return s.getPrincipals(NumericPrincipal.class).iterator().next(); + + return null; + } + public URI getServiceURI(URI standard) { LocalAuthority localAuthority = new LocalAuthority(); return localAuthority.getServiceURI(standard.toString()); } + public AuthMethod getAuthMethod(Subject subject) + { + return AuthenticationUtil.getAuthMethod(subject); + } + /** * Forward on to the Service's user endpoint. * @@ -167,21 +198,19 @@ public class WhoAmIServlet extends HttpServlet * @param webPrincipal The HttpPrincipal instance. * @param scheme The scheme */ - void redirect(final HttpServletResponse response, - final HttpPrincipal webPrincipal, - final String scheme) throws IOException + void redirect(HttpServletResponse response, Principal principal, AuthMethod authMethod) throws IOException { final RegistryClient registryClient = getRegistryClient(); URI umsServiceURI = getServiceURI(Standards.UMS_WHOAMI_01); log.debug("ums service uri: " + umsServiceURI); - final URL serviceURL = registryClient.getServiceURL(umsServiceURI, Standards.UMS_USERS_01, AuthMethod.CERT); + final URL serviceURL = registryClient.getServiceURL(umsServiceURI, Standards.UMS_USERS_01, authMethod); final URL redirectURL = new URL(serviceURL.toExternalForm() + USER_GET_PATH); // Take the first one. final String redirectUrl = - String.format(redirectURL.toString(), webPrincipal.getName()); + String.format(redirectURL.toString(), principal.getName(), AuthenticationUtil.getPrincipalType(principal)); final URI redirectURI = URI.create(redirectUrl); log.debug("redirecting to " + redirectURI.toASCIIString()); diff --git a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/ldap/AbstractLdapDAOTest.java b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/ldap/AbstractLdapDAOTest.java index 592b6b12a5511e768f8beee976b5688820ff9aed..53f99bdd5cf5a262a58e8f4ff955c143f2c3f551 100644 --- a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/ldap/AbstractLdapDAOTest.java +++ b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/ldap/AbstractLdapDAOTest.java @@ -131,7 +131,7 @@ public class AbstractLdapDAOTest public static void setUpBeforeClass() throws Exception { - Log4jInit.setLevel("ca.nrc.cadc.ac", Level.DEBUG); + Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); System.setProperty(PropertiesReader.class.getName() + ".dir", "src/test/resources"); diff --git a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/WhoAmIServletTest.java b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/WhoAmIServletTest.java index 6b374453ab0cb1bf1e077c9a10b5cebad6214862..a2f215b47dd46162e43edce2dc094851ac41d37a 100644 --- a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/WhoAmIServletTest.java +++ b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/WhoAmIServletTest.java @@ -79,6 +79,7 @@ import java.net.URL; import java.security.PrivilegedExceptionAction; import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -114,10 +115,23 @@ public class WhoAmIServletTest } @Test - public void doGet() throws Exception + public void doGetWithHttpPrincipal() throws Exception { final Subject subject = new Subject(); subject.getPrincipals().add(new HttpPrincipal("CADCtest")); + doGet(subject, AuthMethod.PASSWORD, "CADCtest", "http"); + } + + @Test + public void doGetWithCert() throws Exception + { + final Subject subject = new Subject(); + subject.getPrincipals().add(new X500Principal("CN=cadcauthtest1_24c,OU=cadc,O=hia,C=ca")); + doGet(subject, AuthMethod.CERT, "CN=cadcauthtest1_24c,OU=cadc,O=hia,C=ca", "x500"); + } + + public void doGet(final Subject subject, final AuthMethod authMethod, final String restUserid, final String restType) throws Exception + { final RegistryClient mockRegistry = createMock(RegistryClient.class); final WhoAmIServlet testSubject = new WhoAmIServlet() @@ -145,6 +159,12 @@ public class WhoAmIServletTest { return URI.create("ivo://example.org/ums"); } + + @Override + public AuthMethod getAuthMethod(Subject subject) + { + return authMethod; + } }; final HttpServletRequest mockRequest = @@ -155,9 +175,10 @@ public class WhoAmIServletTest expect(mockRequest.getPathInfo()).andReturn("users/CADCtest").once(); expect(mockRequest.getMethod()).andReturn("GET").once(); expect(mockRequest.getRemoteAddr()).andReturn("mysite.com").once(); - expect(mockRequest.getScheme()).andReturn("http"); - mockResponse.sendRedirect("/ac/users/CADCtest?idType=HTTP"); + String redirect = "/ac/users/" + restUserid + "?idType=" + restType; + log.debug("expected redirect: " + redirect); + mockResponse.sendRedirect(redirect); expectLastCall().once(); URI umsServiceURI = URI.create("ivo://example.org/ums"); @@ -166,7 +187,7 @@ public class WhoAmIServletTest // "http", "/%s?idType=HTTP")). // andReturn(new URL("http://mysite.com/ac/users/CADCtest?idType=HTTP")).once(); - expect(mockRegistry.getServiceURL(umsServiceURI, Standards.UMS_USERS_01, AuthMethod.CERT)) + expect(mockRegistry.getServiceURL(umsServiceURI, Standards.UMS_USERS_01, authMethod)) .andReturn(new URL("http://mysite.com/ac/users")).once(); replay(mockRequest, mockResponse, mockRegistry); diff --git a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberActionTest.java b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberActionTest.java index 8cdc25f978138cb21e8d77ffde365f30f9b83f6d..a8d2c7d548bfbc83ebd788ce75d4c473dee28a14 100644 --- a/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberActionTest.java +++ b/cadc-access-control-server/src/test/java/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberActionTest.java @@ -96,7 +96,7 @@ public class RemoveGroupMemberActionTest @BeforeClass public static void setUpClass() { - Log4jInit.setLevel("ca.nrc.cadc.ac", Level.DEBUG); + Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); } @Test