diff --git a/scripts/vagrant/setup.sh b/scripts/vagrant/setup.sh index 4fde9ec7791..6847413819a 100644 --- a/scripts/vagrant/setup.sh +++ b/scripts/vagrant/setup.sh @@ -43,6 +43,9 @@ cp /dataverse/conf/httpd/conf.d/dataverse.conf /etc/httpd/conf.d/dataverse.conf service httpd start curl -k --sslv3 https://pdurbin.pagekite.me/Shibboleth.sso/Metadata > /downloads/pdurbin.pagekite.me cp -a /etc/shibboleth/shibboleth2.xml /etc/shibboleth/shibboleth2.xml.orig +cp -a /etc/shibboleth/attribute-map.xml /etc/shibboleth/attribute-map.xml.orig +# need more attributes, such as sn, givenName, mail +cp /dataverse/conf/vagrant/etc/shibboleth/attribute-map.xml /etc/shibboleth/attribute-map.xml # FIXME: automate this? #curl 'https://www.testshib.org/cgi-bin/sp2config.cgi?dist=Others&hostname=pdurbin.pagekite.me' > /etc/shibboleth/shibboleth2.xml #cp /dataverse/conf/vagrant/etc/shibboleth/shibboleth2.xml /etc/shibboleth/shibboleth2.xml diff --git a/src/main/java/edu/harvard/iq/dataverse/Shib.java b/src/main/java/edu/harvard/iq/dataverse/Shib.java index acbdaf83e47..f644bb7310e 100644 --- a/src/main/java/edu/harvard/iq/dataverse/Shib.java +++ b/src/main/java/edu/harvard/iq/dataverse/Shib.java @@ -1,12 +1,19 @@ package edu.harvard.iq.dataverse; +import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean; +import edu.harvard.iq.dataverse.authorization.RoleAssigneeDisplayInfo; +import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; +import javax.ejb.EJB; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.view.ViewScoped; +import javax.inject.Inject; import javax.inject.Named; import javax.servlet.http.HttpServletRequest; @@ -16,24 +23,61 @@ public class Shib implements java.io.Serializable { private static final Logger logger = Logger.getLogger(Shib.class.getCanonicalName()); + @Inject + DataverseSession session; + + @EJB + AuthenticationServiceBean authSvc; + HttpServletRequest request; /** * @todo these are the attributes we are getting from the IdP at * testshib.org. What other attributes should we expect? * - * Shib-Identity-Provider:https://idp.testshib.org/idp/shibboleth + * Here is a dump from https://pdurbin.pagekite.me/Shibboleth.sso/Session + * + * Miscellaneous + * + * Session Expiration (barring inactivity): 479 minute(s) + * + * Client Address: 10.0.2.2 + * + * SSO Protocol: urn:oasis:names:tc:SAML:2.0:protocol + * + * Identity Provider: https://idp.testshib.org/idp/shibboleth + * + * Authentication Time: 2014-09-12T17:07:36.137Z + * + * Authentication Context Class: + * urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + * + * Authentication Context Decl: (none) + * * - * eppn:myself@testshib.org * - * affiliation:Member@testshib.org;Staff@testshib.org + * Attributes * - * unscoped-affiliation:Member;Staff + * affiliation: Member@testshib.org;Staff@testshib.org * - * entitlement:urn:mace:dir:entitlement:common-lib-terms + * cn: Me Myself And I * - * persistent-id:https://idp.testshib.org/idp/shibboleth!https://dvn-vm3.hmdc.harvard.edu/shibboleth!5HQ8MY1UftsM82eN3YvtQVAS7v0= + * entitlement: urn:mace:dir:entitlement:common-lib-terms * + * eppn: myself@testshib.org + * + * givenName: Me Myself + * + * persistent-id: + * https://idp.testshib.org/idp/shibboleth!https://pdurbin.pagekite.me/shibboleth!zylzL+NruovU5OOGXDOL576jxfo= + * + * sn: And I + * + * telephoneNumber: 555-5555 + * + * uid: myself + * + * unscoped-affiliation: Member;Staff */ List shibAttrs = Arrays.asList( "Shib-Identity-Provider", @@ -50,10 +94,78 @@ public class Shib implements java.io.Serializable { ); List shibValues = new ArrayList<>(); + /** + * @todo make this configurable? + */ + private final String shibIdpAttribute = "Shib-Identity-Provider"; + private final String uniquePersistentIdentifier = "eppn"; + private final String displayNameAttribute = "cn"; + private boolean debug = false; public void init() { ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); request = (HttpServletRequest) context.getRequest(); + /** + * @todo DRY! put all these similar checks in a function + */ + Object shibIdpObject = request.getAttribute(shibIdpAttribute); + if (shibIdpObject == null) { + throw new RuntimeException("Shibboleth Identity Provider attribute (" + shibIdpAttribute + ") was null"); + } + String shibIdp = shibIdpObject.toString(); + if (shibIdp.isEmpty()) { + throw new RuntimeException("Shibboleth Identity Provider attribute (" + shibIdpAttribute + ") was empty"); + } + Object userIdentifierObject = request.getAttribute(uniquePersistentIdentifier); + if (userIdentifierObject == null) { + throw new RuntimeException("Unique persistent identifer attribute (" + uniquePersistentIdentifier + ") was null"); + } + String userIdentifier = userIdentifierObject.toString(); + if (userIdentifier.isEmpty()) { + throw new RuntimeException("Unique persistent identifer attribute (" + uniquePersistentIdentifier + ") was empty"); + } + Object displayNameObject = request.getAttribute(displayNameAttribute); + if (displayNameObject == null) { + throw new RuntimeException("Display name attribute (" + displayNameAttribute + ") was null"); + } + String displayName = displayNameObject.toString(); + if (displayName.isEmpty()) { + throw new RuntimeException("Display name attribute (" + displayNameAttribute + ") was empty"); + } + + String emailAddress = "FIXMEemailAddress"; + RoleAssigneeDisplayInfo displayInfo = new RoleAssigneeDisplayInfo(displayName, emailAddress); + + String userPersistentId = shibIdp + "|" + userIdentifier; + /** + * @todo where should "shib" be defined? + */ + String authPrvId = "shib"; + AuthenticatedUser au = authSvc.lookupUser(authPrvId, userPersistentId); + if (au != null) { + logger.info("Found " + userPersistentId + ". Logging in."); + session.setUser(au); + } else { + logger.info("Couldn't find " + userPersistentId + ". Creating a new user."); + authSvc.createAuthenticatedUser(authPrvId, userPersistentId, displayInfo); + session.setUser(au); + } + try { +// FacesContext.getCurrentInstance().getExternalContext().redirect("http://pdurbin.pagekite.me"); + FacesContext.getCurrentInstance().getExternalContext().redirect("/dataverse.xhtml"); + } catch (IOException ex) { + Logger.getLogger(Shib.class.getName()).log(Level.SEVERE, null, ex); + } + if (debug) { + printAttributes(request); + } + } + + public List getShibValues() { + return shibValues; + } + + private void printAttributes(HttpServletRequest request) { for (String attr : shibAttrs) { /** @@ -72,9 +184,4 @@ public void init() { } logger.info("shib values: " + shibValues); } - - public List getShibValues() { - return shibValues; - } - } diff --git a/src/main/webapp/loginpage.xhtml b/src/main/webapp/loginpage.xhtml index 081f6cea01f..2468dccbfd0 100644 --- a/src/main/webapp/loginpage.xhtml +++ b/src/main/webapp/loginpage.xhtml @@ -49,8 +49,37 @@ -
-