Skip to content

Instantly share code, notes, and snippets.

@pdurbin
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdurbin/df60717dc0b5cfb4742c to your computer and use it in GitHub Desktop.
Save pdurbin/df60717dc0b5cfb4742c to your computer and use it in GitHub Desktop.
2014-10-30 Code Review for Dataverse User Account, Authentication and Shibboleth
<!DOCTYPE html>
<html>
<head>
<title>2014-10-30 Dataverse 4.0 Code Review for User Accounts, Authentication, and Shibboleth</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
@import url(http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(http://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
@import url(http://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body { font-family: 'Droid Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
.remark-slide-content { font-size: 25px; }
.title h1 { font-size: 70px; }
.agenda { font-size: 26px; }
.footnote {
font-size: 15px;
position: absolute;
bottom: 1em;
left: 3em;
right: 1em;
}
.quote { font-size: 18px; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle, title
# Dataverse 4.0 Code Review:
# User Accounts, Authentication, and Shibboleth
<img src="dataverseproject_logo.jpg" width="300px"/>
2014-10-30
---
class: agenda
# Agenda
- Dataverse in a nutshell
- Brief history of auth in DVN/Dataverse
- Dataverse authentication workflow
- Authentication with local/builtin Dataverse account
- Authentication with Harvard ID through Shibboleth
- Other Shibboleth Identity Providers
- Review create account, forget password/username, and login/logout workflows
- Future authentication with LDAP, OAuth, etc.
---
# Dataverse in a nutshell
.center[
<img src="add-find-learn.png" width="650px"/>
]
---
# Brief history of auth in DVN/Dataverse
<img src="dvn3.png" width="150px"/>**DVN 3.x developed ~2007 - 2013**
- DVN 3.x only supports local accounts
- "Affiliate login" based on IP Groups, EZproxy ([docs](https://github.com/IQSS/dvn/blob/develop/doc/sphinx/source/dataverse-user-main.rst#manage-groups))
- Shibboleth fork: https://github.com/DANS-KNAW/dvn
- LDAP fork: https://github.com/ualbertalib/dvn
<img src="dataverseproject_logo.jpg" width="150px"/>**Dataverse 4.0 developed late 2013 - present **
- Shibboleth first, [dvn-auth list](https://lists.iq.harvard.edu/mailman/roster/dvn-auth): Odum, HMS, DANS, etc.
- IP Groups must stay ([discussion](https://groups.google.com/d/msg/dataverse-community/hQO1UDMa-yY/GlhMVIbYR_8J))
- [Pluggable auth proposal](https://github.com/IQSS/dataverse/blob/master/doc/Architecture/auth.md) ([announcement](https://groups.google.com/d/msg/dataverse-community/ieRom3fCDs4/Uu8HLHPo4WAJ))
- Code contributions for LDAP and OAuth support?
- Preliminary Shibboleth support [announced Oct 2014](http://datascience.iq.harvard.edu/blog/try-out-single-sign-shibboleth-40-beta)
---
# Dataverse authentication workflow
<img src="choose-auth.png" width="700px"/>
<img src="tou.png" width="300px" align="right"/>
Login with local or Shib
On account creation, accept Terms of Use
---
# Set AuthenticatedUser on session
```java
@SessionScoped
public class DataverseSession implements Serializable {
private AuthenticatedUser user;
* public void setUser(AuthenticatedUser user) {
this.user = user;
}
...
}
```
.footnote[
https://github.com/IQSS/dataverse/blob/master/src/main/java/edu/harvard/iq/dataverse/DataverseSession.java
]
---
# Local/Builtin auth
```java
try {
* AuthenticatedUser r = authSvc.authenticate(credentialsAuthProviderId, authReq);
logger.log(Level.INFO, "User authenticated: {0}", r.getEmail());
session.setUser(r);
return "/dataverse.xhtml?faces-redirect=true";
} catch (AuthenticationFailedException ex) {
JH.addMessage(FacesMessage.SEVERITY_ERROR, "Login Failed" ...
return null;
}
```
```java
public AuthenticationResponse authenticate(AuthenticationRequest authReq) {
BuiltinUser u = bean.findByUserName(authReq.getCredential(KEY_USERNAME));
if (u == null) return AuthenticationResponse.makeFail("Bad username or password");
* return (u.getEncryptedPassword()
* .equals(bean.encryptPassword(authReq.getCredential(KEY_PASSWORD))))
? AuthenticationResponse.makeSuccess(u.getUserName(), u.getDisplayInfo())
: AuthenticationResponse.makeFail("Bad username or password");
}
```
.footnote[
https://github.com/IQSS/dataverse/blob/master/src/main/java/edu/harvard/iq/dataverse/LoginPage.java
https://github.com/IQSS/dataverse/blob/master/src/main/java/edu/harvard/iq/dataverse/authorization/providers/builtin/BuiltinAuthenticationProvider.java
]
---
# Shibboleth auth: lookup user
```java
... request.getAttribute(shibIdP) // https://idp.testshib.org/idp/shibboleth
... request.getAttribute(eppn) // af2adbd1a8764@testshib.org
```
```java
userPersistentId = shibIdp + "|" + userIdentifier;
*AuthenticatedUser au = authSvc.lookupUser(authPrvId, userPersistentId);
if (au != null) {
logger.info("Found user based on " + userPersistentId + ". Logging in.");
* session.setUser(au); // send user to homepage
...
} else {
logger.info("Couldn't find authenticated user based on " + userPersistentId);
visibleTermsOfUse = true; // must accept Terms of Use
}
```
eduPersonPrincipalName (eppn) vs. eduPersonTargetedID (ePTID): https://lists.iq.harvard.edu/pipermail/dvn-auth/2014-July/000016.html
.footnote[
https://github.com/IQSS/dataverse/issues/963
https://github.com/IQSS/dataverse/blob/master/src/main/java/edu/harvard/iq/dataverse/Shib.java
]
---
# Shibboleth auth: create user
```java
public String confirm() {
logger.info("confirm called...");
AuthenticatedUser au =
* authSvc.createAuthenticatedUser(authPrvId, userPersistentId, displayInfo);
session.setUser(au);
return homepage + "?faces-redirect=true";
}
```
.footnote[
https://github.com/IQSS/dataverse/issues/963
https://github.com/IQSS/dataverse/blob/master/src/main/java/edu/harvard/iq/dataverse/Shib.java
]
---
# Shibboleth and API keys/tokens
The dilemma:
- Many Dataverse users will auth with Shibboleth
- Some of those users will want APIs tokens
- How do you use an API token with Shibboleth?
---
# Shibboleth problems
* [User sessions mixed up when Java app deployed to Glassfish is fronted with Apache httpd](http://shibboleth.net/pipermail/users/2014-October/017878.html) ([Issue #647](https://github.com/IQSS/dataverse/issues/647))
<img src="scrambled-session.png" width="500px"/>
* Can log out of Dataverse but Shibboleth session is still active until browser is closed
.quote[
"Since Shibboleth was developed, one of the most requested features has been Single Logout (SLO). Our lists are full of threads indicating that this feature is not as easy as it seems. This document is an attempt to collect and expound upon the difficulties of SLO."
-- https://wiki.shibboleth.net/confluence/display/SHIB2/SLOIssues
]
---
# Password reset (local/builtin accounts)
<img src="pwreset-workflow.png" width="350px" align="right"/>
Hide usernames from attackers
Always say you're sending an email
Delete token on use
Expire token
Optional steps could be added
.footnote[
http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html
via https://github.com/IQSS/dataverse/issues/416
https://github.com/IQSS/dataverse/tree/master/src/main/java/edu/harvard/iq/dataverse/passwordreset
]
---
# Future auth: LDAP, OAuth, etc.
LDAP fork: https://github.com/ualbertalib/dvn
Interest in contributing: https://groups.google.com/d/msg/dataverse-community/G6e-9Zz-bPY/VkzvG0xtVP4J
</textarea>
<script src="http://gnab.github.io/remark/downloads/remark-latest.min.js" type="text/javascript">
</script>
<script type="text/javascript">
var slideshow = remark.create();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment