mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-17 23:13:10 +00:00
[DS-3819] Revert back to 401 status and move login URL to WWW-Authenticate header
This commit is contained in:
@@ -210,4 +210,10 @@ public interface AuthenticationMethod {
|
|||||||
public String loginPageURL(Context context,
|
public String loginPageURL(Context context,
|
||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response);
|
HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a short name that uniquely identifies this authentication method
|
||||||
|
* @return The authentication method name
|
||||||
|
*/
|
||||||
|
public String getName();
|
||||||
}
|
}
|
||||||
|
@@ -276,4 +276,9 @@ public class IPAuthentication implements AuthenticationMethod {
|
|||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ip";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -639,6 +639,11 @@ public class LDAPAuthentication
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ldap";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add authenticated users to the group defined in dspace.cfg by
|
* Add authenticated users to the group defined in dspace.cfg by
|
||||||
* the authentication-ldap.login.groupmap.* key.
|
* the authentication-ldap.login.groupmap.* key.
|
||||||
|
@@ -242,4 +242,9 @@ public class PasswordAuthentication
|
|||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "password";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -538,6 +538,11 @@ public class ShibAuthentication implements AuthenticationMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "shibboleth";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identify an existing EPerson based upon the shibboleth attributes provided on
|
* Identify an existing EPerson based upon the shibboleth attributes provided on
|
||||||
* the request object. There are three cases where this can occurr, each as
|
* the request object. There are three cases where this can occurr, each as
|
||||||
|
@@ -589,4 +589,9 @@ public class X509Authentication implements AuthenticationMethod {
|
|||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
return loginPageURL;
|
return loginPageURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "x509";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -82,26 +82,26 @@ public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter
|
|||||||
Iterator<AuthenticationMethod> authenticationMethodIterator
|
Iterator<AuthenticationMethod> authenticationMethodIterator
|
||||||
= authenticationService.authenticationMethodIterator();
|
= authenticationService.authenticationMethodIterator();
|
||||||
Context context = ContextUtil.obtainContext(request);
|
Context context = ContextUtil.obtainContext(request);
|
||||||
String redirectUrl = null;
|
|
||||||
|
|
||||||
|
StringBuilder wwwAuthenticate = new StringBuilder();
|
||||||
while (authenticationMethodIterator.hasNext()) {
|
while (authenticationMethodIterator.hasNext()) {
|
||||||
AuthenticationMethod authenticationMethod = authenticationMethodIterator.next();
|
AuthenticationMethod authenticationMethod = authenticationMethodIterator.next();
|
||||||
|
|
||||||
|
if (wwwAuthenticate.length() > 0) {
|
||||||
|
wwwAuthenticate.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
wwwAuthenticate.append(authenticationMethod.getName()).append(" realm=\"DSpace REST API\"");
|
||||||
|
|
||||||
String loginPageURL = authenticationMethod.loginPageURL(context, request, response);
|
String loginPageURL = authenticationMethod.loginPageURL(context, request, response);
|
||||||
if (StringUtils.isNotBlank(loginPageURL)) {
|
if (StringUtils.isNotBlank(loginPageURL)) {
|
||||||
redirectUrl = loginPageURL;
|
// We cannot reply with a 303 code because may browsers handle 3xx response codes transparently. This
|
||||||
|
// means that the JavaScript client code is not aware of the 303 status and fails to react accordingly.
|
||||||
|
wwwAuthenticate.append(", location=\"").append(loginPageURL).append("\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String wwwAuthenticate = "Bearer realm=\"DSpace REST API\"";
|
response.setHeader("WWW-Authenticate", wwwAuthenticate.toString());
|
||||||
if (redirectUrl != null) {
|
|
||||||
//We cannot reply with a 303 code because may browsers handle 3xx response codes transparently.
|
|
||||||
//This means that the JavaScript client code is not aware of the 303 status and fails to react accordingly.
|
|
||||||
wwwAuthenticate = wwwAuthenticate + ", location=\"" + redirectUrl + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
response.setHeader("WWW-Authenticate", wwwAuthenticate);
|
|
||||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, failed.getMessage());
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, failed.getMessage());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -91,7 +91,7 @@
|
|||||||
type : 'POST',
|
type : 'POST',
|
||||||
success : successHandler,
|
success : successHandler,
|
||||||
error : function(result, status, xhr) {
|
error : function(result, status, xhr) {
|
||||||
if (xhr == 401) {
|
if (result.status === 401) {
|
||||||
var authenticate = result.getResponseHeader("WWW-Authenticate");
|
var authenticate = result.getResponseHeader("WWW-Authenticate");
|
||||||
if(authenticate !== null) {
|
if(authenticate !== null) {
|
||||||
var loc = /location="([^,]*)"/.exec(authenticate);
|
var loc = /location="([^,]*)"/.exec(authenticate);
|
||||||
|
@@ -344,6 +344,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShibbolethLoginRequestAttribute() throws Exception {
|
public void testShibbolethLoginRequestAttribute() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
//Enable Shibboleth login
|
//Enable Shibboleth login
|
||||||
configurationService.setProperty("plugin.sequence.org.dspace.authenticate.AuthenticationMethod", SHIB_ONLY);
|
configurationService.setProperty("plugin.sequence.org.dspace.authenticate.AuthenticationMethod", SHIB_ONLY);
|
||||||
|
|
||||||
@@ -354,18 +355,19 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
|
|||||||
|
|
||||||
//Faculty members are assigned to the Reviewers group
|
//Faculty members are assigned to the Reviewers group
|
||||||
configurationService.setProperty("authentication-shibboleth.role.faculty", "Reviewers");
|
configurationService.setProperty("authentication-shibboleth.role.faculty", "Reviewers");
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
getClient().perform(get("/api/authn/login").header("Referer", "http://my.uni.edu"))
|
getClient().perform(get("/api/authn/login").header("Referer", "http://my.uni.edu"))
|
||||||
.andExpect(status().isUnauthorized())
|
.andExpect(status().isUnauthorized())
|
||||||
.andExpect(header().string("WWW-Authenticate",
|
.andExpect(header().string("WWW-Authenticate",
|
||||||
"Bearer realm=\"DSpace REST API\", " +
|
"shibboleth realm=\"DSpace REST API\", " +
|
||||||
"location=\"/Shibboleth.sso/Login?target=http%3A%2F%2Fmy.uni.edu\""));
|
"location=\"/Shibboleth.sso/Login?target=http%3A%2F%2Fmy.uni.edu\""));
|
||||||
|
|
||||||
//Simulate that a shibboleth authentication has happened
|
//Simulate that a shibboleth authentication has happened
|
||||||
|
|
||||||
String token = getClient().perform(post("/api/authn/login")
|
String token = getClient().perform(post("/api/authn/login")
|
||||||
.requestAttr("SHIB-MAIL", eperson.getEmail())
|
.requestAttr("SHIB-MAIL", eperson.getEmail())
|
||||||
.requestAttr("SHIB-SCOPED-AFFILIATION", "faculty,staff"))
|
.requestAttr("SHIB-SCOPED-AFFILIATION", "faculty;staff"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andReturn().getResponse().getHeader(AUTHORIZATION_HEADER);
|
.andReturn().getResponse().getHeader(AUTHORIZATION_HEADER);
|
||||||
|
|
||||||
@@ -393,7 +395,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
|
|||||||
.with(ip("123.123.123.123")))
|
.with(ip("123.123.123.123")))
|
||||||
.andExpect(status().isUnauthorized())
|
.andExpect(status().isUnauthorized())
|
||||||
.andExpect(header().string("WWW-Authenticate",
|
.andExpect(header().string("WWW-Authenticate",
|
||||||
"Bearer realm=\"DSpace REST API\", " +
|
"ip realm=\"DSpace REST API\", shibboleth realm=\"DSpace REST API\", " +
|
||||||
"location=\"/Shibboleth.sso/Login?target=http%3A%2F%2Fmy.uni.edu\""));
|
"location=\"/Shibboleth.sso/Login?target=http%3A%2F%2Fmy.uni.edu\""));
|
||||||
|
|
||||||
//Simulate that a shibboleth authentication has happened
|
//Simulate that a shibboleth authentication has happened
|
||||||
|
Reference in New Issue
Block a user