diff --git a/projects/cadcAccessControl-Server/build.xml b/projects/cadcAccessControl-Server/build.xml index b5ad9f91fe28e1e3606f3b6ab652d333b722271e..e0c3d437bd12e91bc5d87e5548d35b5cfc66d065 100644 --- a/projects/cadcAccessControl-Server/build.xml +++ b/projects/cadcAccessControl-Server/build.xml @@ -93,6 +93,7 @@ <property name="cadcUtil" value="${lib}/cadcUtil.jar"/> <property name="cadcUWS" value="${lib}/cadcUWS.jar"/> <property name="wsUtil" value="${lib}/wsUtil.jar"/> + <property name="wsUtil-augment" value="${lib}/wsUtil-augment.jar"/> <property name="javacsv" value="${ext.lib}/javacsv.jar"/> <property name="jdom2" value="${ext.lib}/jdom2.jar"/> @@ -102,7 +103,7 @@ <property name="xerces" value="${ext.lib}/xerces.jar"/> <property name="jars" - value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${wsUtil}"/> + value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${wsUtil}:${wsUtil-augment}"/> <target name="build" depends="compile"> <jar jarfile="${build}/lib/${project}.jar" diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java index 92a345af5cc7383779cab27f99f37d8819dc8ee0..7442a6896a6438ea878d7809a69645198be3af7f 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java @@ -71,6 +71,8 @@ import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.server.UserPersistence; +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; import java.security.AccessControlContext; import java.security.AccessController; @@ -79,10 +81,12 @@ import java.security.PrivilegedExceptionAction; import java.util.Set; import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; + public class GetUserAction extends AbstractUserAction { private static final Logger log = Logger.getLogger(GetUserAction.class); @@ -100,14 +104,14 @@ public class GetUserAction extends AbstractUserAction { User<Principal> user; - if (isServops()) + if (isAugmentUser()) { - Subject subject = new Subject(); + Subject subject = new Subject(); subject.getPrincipals().add(this.userID); - user = (User<Principal>) Subject.doAs(subject, new PrivilegedExceptionAction<Object>() + user = Subject.doAs(subject, new PrivilegedExceptionAction<User<Principal>>() { @Override - public Object run() throws Exception + public User<Principal> run() throws Exception { return getUser(userID); } @@ -130,58 +134,57 @@ public class GetUserAction extends AbstractUserAction try { user = userPersistence.getUser(principal); - if (detail != null) - { - // Only return user principals - if (detail.equals("identity")) - { - user.details.clear(); - } - // Only return user profile info, first and last name. - else if (detail.equals("display")) - { - user.getIdentities().clear(); - Set<PersonalDetails> details = user.getDetails(PersonalDetails.class); - if (details.isEmpty()) - { - String error = principal.getName() + " missing required PersonalDetails"; - throw new IllegalStateException(error); - } - PersonalDetails pd = details.iterator().next(); - user.details.clear(); - user.details.add(new PersonalDetails(pd.getFirstName(), pd.getLastName())); - } - else - { - throw new IllegalArgumentException("Illegal detail parameter " + detail); - } - } } catch (UserNotFoundException e) { user = userPersistence.getPendingUser(principal); } - return user; + if (detail != null) + { + // Only return user principals + if (detail.equals("identity")) + { + user.details.clear(); + } + // Only return user profile info, first and last name. + else if (detail.equals("display")) + { + user.getIdentities().clear(); + Set<PersonalDetails> details = user.getDetails(PersonalDetails.class); + if (details.isEmpty()) + { + String error = principal.getName() + " missing required PersonalDetails"; + throw new IllegalStateException(error); + } + PersonalDetails pd = details.iterator().next(); + user.details.clear(); + user.details.add(new PersonalDetails(pd.getFirstName(), pd.getLastName())); + } + else + { + throw new IllegalArgumentException("Illegal detail parameter " + detail); + } + } + + return user; } - protected boolean isServops() + protected boolean isAugmentUser() { - boolean isServops = false; AccessControlContext acc = AccessController.getContext(); Subject subject = Subject.getSubject(acc); if (subject != null) { - for (Principal principal : subject.getPrincipals()) + for (Principal principal : subject.getPrincipals(HttpPrincipal.class)) { - if (principal.getName().equals(this.getAugmentUserDN())) + if (principal.getName().equals(this.getAugmentUserDN())) { - isServops = true; - break; + return true; } } } - return isServops; + return false; } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java index 457dd4b1b686ef42092abd6378945affbf82ed05..30583c7ff083819565324705e964097eb6cc743f 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java @@ -68,17 +68,18 @@ */ package ca.nrc.cadc.ac.server.web.users; -import ca.nrc.cadc.ac.IdentityType; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.server.web.WebUtil; import ca.nrc.cadc.auth.CookiePrincipal; import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.IdentityType; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; import java.io.IOException; import java.net.URL; import java.security.Principal; + import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java index 6fbb19c354a93371a55156836e135a8394784f0f..6dedcc71833bd72d4206f9e0b989b17e05b2a046 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java @@ -90,7 +90,7 @@ public class UserServlet extends HttpServlet private static final long serialVersionUID = 5289130885807305288L; private static final Logger log = Logger.getLogger(UserServlet.class); - private String augmentUserDN; + private String augmentUser; @Override public void init(final ServletConfig config) throws ServletException @@ -99,8 +99,8 @@ public class UserServlet extends HttpServlet try { - this.augmentUserDN = config.getInitParameter(UserServlet.class.getName() + ".augmentUserDN"); - log.info("augmentUserDN: " + augmentUserDN); + this.augmentUser = config.getInitParameter(UserServlet.class.getName() + ".augmentUser"); + log.info("augmentUser: " + augmentUser); } catch(Exception ex) { @@ -126,7 +126,7 @@ public class UserServlet extends HttpServlet AbstractUserAction action = factory.createAction(request); SyncOutput syncOut = new SyncOutput(response); - action.setAugmentUserDN(this.augmentUserDN); + action.setAugmentUserDN(this.augmentUser); action.setLogInfo(logInfo); action.setSyncOut(syncOut); action.setAcceptedContentType(getAcceptedContentType(request)); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/RequestValidatorTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/RequestValidatorTest.java index e54ea3da63d1689021d071ae82a86d58c12952f6..87abcdac7c5d70b2aadf0aca0aba438ae04ecbdd 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/RequestValidatorTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/RequestValidatorTest.java @@ -71,15 +71,18 @@ package ca.nrc.cadc.ac.server; import ca.nrc.cadc.ac.Role; import ca.nrc.cadc.ac.server.web.groups.AddUserMemberActionTest; import ca.nrc.cadc.auth.AuthenticationUtil; +import ca.nrc.cadc.auth.IdentityType; import ca.nrc.cadc.util.Log4jInit; import ca.nrc.cadc.uws.Parameter; import java.util.ArrayList; import java.util.List; + import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.junit.BeforeClass; import org.junit.Test; + import static org.junit.Assert.*; /** @@ -152,7 +155,7 @@ public class RequestValidatorTest paramList.clear(); paramList.add(new Parameter("ID", "foo")); - paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP)); + paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue())); paramList.add(new Parameter("ROLE", "foo")); try { @@ -163,7 +166,7 @@ public class RequestValidatorTest paramList.clear(); paramList.add(new Parameter("ID", "foo")); - paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP)); + paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue())); paramList.add(new Parameter("ROLE", "foo")); paramList.add(new Parameter("GROUPID", "")); try @@ -175,7 +178,7 @@ public class RequestValidatorTest paramList.clear(); paramList.add(new Parameter("ID", "foo")); - paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP)); + paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue())); paramList.add(new Parameter("ROLE", Role.MEMBER.getValue())); rv.validate(paramList); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberActionTest.java index 8eae8ace9c01d0fce6d452861e0f61030008e954..d079de6f350de9ea7fd41bef8e3a671c68c5b52e 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberActionTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberActionTest.java @@ -74,7 +74,9 @@ import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.server.GroupPersistence; import ca.nrc.cadc.ac.server.UserPersistence; import ca.nrc.cadc.auth.AuthenticationUtil; +import ca.nrc.cadc.auth.IdentityType; import ca.nrc.cadc.util.Log4jInit; + import java.security.Principal; import org.apache.log4j.Level; @@ -107,7 +109,7 @@ public class AddUserMemberActionTest try { String userID = "foo"; - String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP; + String userIDType = IdentityType.USERNAME.getValue(); Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType); User<Principal> user = new User<Principal>(userPrincipal); @@ -159,7 +161,7 @@ public class AddUserMemberActionTest try { String userID = "foo"; - String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP; + String userIDType = IdentityType.USERNAME.getValue(); Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType); User<Principal> user = new User<Principal>(userPrincipal); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberActionTest.java index 92f5263dabbed86331eb015a9e0098bc02a146b0..dcba09b625bbd5830640710fe4cc780bf1faf7f1 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberActionTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberActionTest.java @@ -74,8 +74,11 @@ import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.server.GroupPersistence; import ca.nrc.cadc.ac.server.UserPersistence; import ca.nrc.cadc.auth.AuthenticationUtil; +import ca.nrc.cadc.auth.IdentityType; import ca.nrc.cadc.util.Log4jInit; + import java.security.Principal; + import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.easymock.EasyMock; @@ -106,7 +109,7 @@ public class RemoveUserMemberActionTest try { String userID = "foo"; - String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP; + String userIDType = IdentityType.USERNAME.getValue(); Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType); User<Principal> user = new User<Principal>(userPrincipal); @@ -156,7 +159,7 @@ public class RemoveUserMemberActionTest try { String userID = "foo"; - String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP; + String userIDType = IdentityType.USERNAME.getValue(); Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType); User<Principal> user = new User<Principal>(userPrincipal); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java index a22a7519f360b2598a9728110b0163e6dfab2f3c..081a0cdfa23de83ad11c3c2c5abd1c24f5882c1d 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java @@ -71,25 +71,18 @@ package ca.nrc.cadc.ac.client; import java.io.*; import java.net.MalformedURLException; import java.net.URL; -import java.net.URLEncoder; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.Principal; +import java.util.Iterator; import java.util.Set; -import javax.net.ssl.SSLSocketFactory; import javax.security.auth.Subject; -import javax.security.auth.x500.X500Principal; import ca.nrc.cadc.ac.*; -import ca.nrc.cadc.auth.HttpPrincipal; import org.apache.log4j.Logger; import ca.nrc.cadc.ac.xml.UserReader; -import ca.nrc.cadc.auth.CookiePrincipal; -import ca.nrc.cadc.auth.NumericPrincipal; -import ca.nrc.cadc.auth.SSLUtil; +import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.net.HttpDownload; @@ -102,8 +95,6 @@ public class UserClient private static final Logger log = Logger.getLogger(UserClient.class); // socket factory to use when connecting - private SSLSocketFactory sslSocketFactory; - private SSLSocketFactory mySocketFactory; private String baseURL; /** @@ -148,52 +139,40 @@ public class UserClient */ public void augmentSubject(Subject subject) { - URL url = this.getURL(subject); - log.debug("augmentSubject request to " + url.toString()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - HttpDownload download = new HttpDownload(url, out); - - download.setSSLSocketFactory(getSSLSocketFactory()); - download.run(); - - this.handleThrowable(download); - this.augmentSubject(subject, this.getPrincipals(out)); + Principal principal = this.getPrincipal(subject); + if (principal != null) + { + URL url = this.getURL(principal); + log.debug("augmentSubject request to " + url.toString()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + HttpDownload download = new HttpDownload(url, out); + download.run(); + + this.handleThrowable(download); + subject.getPrincipals().clear(); + subject.getPrincipals().addAll(this.getPrincipals(out)); + } } - protected void augmentSubject(Subject subject, Set<Principal> principals) + protected Principal getPrincipal(final Subject subject) { - if (principals.isEmpty()) - { - String name = subject.getPrincipals().iterator().next().getName(); - String msg = "No UserIdentity in LDAP server for principal: " + name; - throw new IllegalStateException(msg); - } - - for (Principal principal : principals) + Set<Principal> principals = subject.getPrincipals(); + Iterator<Principal> iterator = principals.iterator(); + if (iterator.hasNext()) { - if (principal instanceof HttpPrincipal) + Principal principal = iterator.next(); + if (iterator.hasNext()) { - subject.getPrincipals().add((HttpPrincipal)principal); - } - else if (principal instanceof X500Principal) - { - subject.getPrincipals().add((X500Principal)principal); - } - else if (principal instanceof NumericPrincipal) - { - subject.getPrincipals().add((NumericPrincipal)principal); - } - else if (principal instanceof CookiePrincipal) - { - subject.getPrincipals().add((CookiePrincipal)principal); - } - else - { - final String msg = "Subject has unsupported principal " + - principal.getName() + - ", not one of (X500, Cookie, HTTP or Cadc)."; - throw new IllegalStateException(msg); + // Should only have one principal + final String msg = "Subject has more than one principal."; + throw new IllegalArgumentException(msg); } + + return principal; + } + else + { + return null; } } @@ -224,127 +203,34 @@ public class UserClient } } - protected URL getURL(Subject subject) + protected URL getURL(Principal principal) { try { - String userID = subject.getPrincipals().iterator().next().getName(); - String encodedUserID = URLEncoder.encode(userID, "UTF-8"); - URL url = new URL(this.baseURL + "/users/" + encodedUserID + - "?idType=" + this.getIdType(subject) + "&detail=identity"); + String userID = principal.getName(); + URL url = new URL(this.baseURL + "/users/" + userID + + "?idType=" + this.getIdType(principal) + "&detail=identity"); log.debug("getURL(): returned url =" + "" + " " + url.toString()); return url; } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e); - } catch (MalformedURLException e) { throw new RuntimeException(e); } } - protected String getIdType(Subject subject) - { - Set<Principal> principals = subject.getPrincipals(); - if (principals.size() > 0) - { - String idTypeStr = null; - Principal principal = principals.iterator().next(); - if (principal instanceof HttpPrincipal) - { - idTypeStr = IdentityType.USERNAME.getValue(); - } - else if (principal instanceof X500Principal) - { - idTypeStr = IdentityType.X500.getValue(); - } - else if (principal instanceof NumericPrincipal) - { - idTypeStr = IdentityType.CADC.getValue(); - } - else if (principal instanceof CookiePrincipal) - { - idTypeStr = IdentityType.COOKIE.getValue(); - } - else - { - final String msg = "Subject has unsupported principal " + - principal.getName() + - ", not one of (X500, Cookie, HTTP or Cadc)."; - throw new IllegalArgumentException(msg); - } - - return idTypeStr; - } - else - { - final String msg = "Subject has no principal."; - throw new IllegalArgumentException(msg); - } - } - - /** - * @param sslSocketFactory the sslSocketFactory to set - */ - public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) - { - if (mySocketFactory != null) - { - throw new IllegalStateException( - "Illegal use of GMSClient: cannot set SSLSocketFactory " + - "after using one created from Subject"); - } - this.sslSocketFactory = sslSocketFactory; - clearCache(); - } - - private int subjectHashCode = 0; - - private SSLSocketFactory getSSLSocketFactory() - { - AccessControlContext ac = AccessController.getContext(); - Subject s = Subject.getSubject(ac); - - // no real Subject: can only use the one from setSSLSocketFactory - if (s == null || s.getPrincipals().isEmpty()) - { - return sslSocketFactory; - } - - // lazy init - if (this.mySocketFactory == null) - { - log.debug("getSSLSocketFactory: " + s); - this.mySocketFactory = SSLUtil.getSocketFactory(s); - this.subjectHashCode = s.hashCode(); - } - else - { - int c = s.hashCode(); - if (c != subjectHashCode) - { - throw new IllegalStateException( - "Illegal use of " + this.getClass().getSimpleName() + - ": subject change not supported for internal " + - "SSLSocketFactory"); - } - } - return this.mySocketFactory; - } - - protected void clearCache() + protected String getIdType(Principal principal) { - AccessControlContext acContext = AccessController.getContext(); - Subject subject = Subject.getSubject(acContext); - - if (subject != null) + String idTypeStr = AuthenticationUtil.getPrincipalType(principal); + if (idTypeStr == null) { - log.debug("Clearing cache"); - subject.getPrivateCredentials().clear(); + final String msg = "Subject has unsupported principal " + + principal.getName(); + throw new IllegalArgumentException(msg); } + + return idTypeStr; } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java index 7401185b0487eafa718057a3fa74732f74f0e6bc..732e406596b8cadc758526c86342742ebd4ccd1c 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java @@ -72,7 +72,6 @@ package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.AC; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.GroupProperty; -import ca.nrc.cadc.ac.IdentityType; import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.PosixDetails; import ca.nrc.cadc.ac.ReaderException; @@ -81,9 +80,11 @@ import ca.nrc.cadc.ac.UserDetails; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.IdentityType; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; import ca.nrc.cadc.date.DateUtil; + import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; @@ -91,6 +92,7 @@ import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import javax.security.auth.x500.X500Principal; + import java.io.IOException; import java.io.Writer; import java.security.Principal;