Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented passive authentication support for Shibboleth #3762

Merged
merged 2 commits into from
Apr 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -603,3 +603,18 @@ or
Dataverse calculates checksums for uploaded files so that users can determine if their file was corrupted via upload or download. This is sometimes called "file fixity": https://en.wikipedia.org/wiki/File_Fixity

The default checksum algorithm used is MD5 and should be sufficient for establishing file fixity. "SHA-1" is an experimental alternate value for this setting.

:ShibPassiveLoginEnabled
++++++++++++++++++++++++

Set ``ShibPassiveLoginEnabled`` to true to enable passive login for Shibboleth. When this feature is enabled, an additional Javascript file (isPassive.js) will be loaded for every page. It will generate a passive login request to your Shibboleth SP when an anonymous user navigates to the site. A cookie named "_check_is_passive_dv" will be created to keep track of whether or not a passive login request has already been made for the user.

This implementation follows the example on the Shibboleth wiki documentation page for the isPassive feature: https://wiki.shibboleth.net/confluence/display/SHIB2/isPassive

It is recommended that you configure additional error handling for your Service Provider if you enable passive login. A good way of doing this is described in the Shibboleth wiki documentation:

- *In your Service Provider 2.x shibboleth2.xml file, add redirectErrors="#THIS PAGE#" to the Errors element.*

You can set the value of "#THIS PAGE#" to the url of your Dataverse homepage, or any other page on your site that is accessible to anonymous users and will have the isPassive.js file loaded.

``curl -X PUT -d true http://localhost:8080/api/admin/settings/:ShibPassiveLoginEnabled``
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ public enum Key {
/*
Whether Harvesting (OAI) service is enabled
*/
OAIServerEnabled;
OAIServerEnabled,

/**
* Whether Shibboleth passive authentication mode is enabled
*/
ShibPassiveLoginEnabled;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, you'd document this new database setting so that it appears (near the bottom) of a future version of http://guides.dataverse.org/en/4.6.1/installation/config.html#database-settings


@Override
public String toString() {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -642,5 +642,10 @@ public String getOAuth2CallbackUrl() {
}
return saneDefault;
}

public boolean isShibPassiveLoginEnabled() {
boolean defaultResponse = false;
return settingsService.isTrueForKey(SettingsServiceBean.Key.ShibPassiveLoginEnabled, defaultResponse);
}

}
5 changes: 4 additions & 1 deletion src/main/webapp/dataverse_template.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@
<script type="text/javascript" defer="defer" src="#{resource['js/dv_rebind_bootstrap_ui.js']}?version=#{systemConfig.getVersion()}"></script>
<script type="text/javascript" defer="defer" src="#{resource['js/owl.carousel.js']}?version=#{systemConfig.getVersion()}"></script>
<script type="text/javascript" defer="defer" src="#{resource['js/jquery.matchHeight.js']}?version=#{systemConfig.getVersion()}"></script>
<script type="text/javascript" defer="defer" src="#{resource['js/jquery.sharrre.js']}?version=#{systemConfig.getVersion()}"></script>
<script type="text/javascript" defer="defer" src="#{resource['js/jquery.sharrre.js']}?version=#{systemConfig.getVersion()}"></script>
<ui:fragment rendered="#{systemConfig.isShibPassiveLoginEnabled()}">
<script type="text/javascript" language="javascript" src="#{resource['js/shib/isPassive.js']}"></script>
</ui:fragment>
<script>
$(document).ready(function () {
// Navbar Search Toggle
Expand Down
42 changes: 42 additions & 0 deletions src/main/webapp/resources/js/shib/isPassive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
This isPassive script will automatically try to log in a user using the SAML2
isPassive feature.
In case a user already has an authenticated session at his Identity Provider and
given the Discovery Service can guess the user's Identity Provider, the user will
eventually be on the exact same page this script is embedded in but logged in
(= Shibboleth attributes are available and user has a valid session with the
Service Provider on the same host).
The user page also will be requested with the same GET arguments than the initial request.

Requirements:
- Only works if a Service Provider 2.x is installed on the same host
- JavaScript must be enabled. Otherwise the script won't have any effect.
- The script must be able to set cookies (required for Shibboleth Service Provider as well)
- In the shibboleth2.xml there must be defined a redirectErrors="#THIS PAGE#" in
the <Errors> element. #THIS PAGE# must be the relative/absolute URL of the page
this script is embedded in.
- It also makes sense to protect #THIS PAGE# with a lazy session in order to use
the Shibboleth attribute that should be available after authentication.
*/

// Check for session cookie that contains the initial location
if(document.cookie && document.cookie.search(/_check_is_passive_dv=/) >= 0){
// If we have the opensaml::FatalProfileException GET arguments
// redirect to initial location because isPassive failed
if (
window.location.search.search(/errorType/) >= 0
&& window.location.search.search(/RelayState/) >= 0
&& window.location.search.search(/requestURL/) >= 0
) {
var cookieStr = document.cookie + ";";
var startpos = (cookieStr.indexOf('_check_is_passive_dv=')+21);
var endpos = cookieStr.indexOf(';', startpos);
window.location = cookieStr.substring(startpos,endpos);
}
} else {
// Mark browser as being isPassive checked
document.cookie = "_check_is_passive_dv=" + window.location;

// Redirect to Shibboleth handler
window.location = "/Shibboleth.sso/Login?isPassive=true&target=" + encodeURIComponent("https://" + window.location.hostname + "/shib.xhtml?redirectPage=" + window.location.pathname);
}