Commit e29bf705 authored by Patrick Dowler's avatar Patrick Dowler Committed by GitHub
Browse files

Merge pull request #20 from brianmajor/master

issue-19 - WhoAmIServlet supports different AuthMethods
parents 11a5869e 7cbc62a8
......@@ -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.+'
......
......@@ -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());
......
......@@ -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");
......
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment