Skip to content

Commit 2e92ed8

Browse files
UFAL/Shibboleth - show error in the UI when shibboleth authentication is failed (#810)
* The user is not signed in without using link with the verification token from the email/ * Send a redirect to UI with specific parameter that the Shibboleth authorization wasn't successful
1 parent 9f8d2c5 commit 2e92ed8

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

dspace-api/src/main/java/org/dspace/core/Utils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,4 +506,21 @@ public static String interpolateConfigsInString(String string) {
506506
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
507507
return StringSubstitutor.replace(string, config.getProperties());
508508
}
509+
510+
/**
511+
* Replace the last occurrence of a substring within a string.
512+
*
513+
* @param input The input string
514+
* @param toReplace The substring to replace
515+
* @param replacement The replacement substring
516+
* @return Replaced input string or the original input string if the substring to replace is not found
517+
*/
518+
public static String replaceLast(String input, String toReplace, String replacement) {
519+
int lastIndex = input.lastIndexOf(toReplace);
520+
if (lastIndex == -1) {
521+
return input; // No replacement if not found
522+
}
523+
524+
return input.substring(0, lastIndex) + replacement + input.substring(lastIndex + toReplace.length());
525+
}
509526
}

dspace-api/src/test/java/org/dspace/core/UtilsTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,24 @@ public void testInterpolateConfigsInString() {
132132
// remove the config we added
133133
configurationService.setProperty(configName, null);
134134
}
135+
136+
// Replace the last occurrence of a substring
137+
@Test
138+
public void testReplaceLast_SingleOccurrence() {
139+
String input = "/login/";
140+
String result = Utils.replaceLast(input, "/", "replacement");
141+
142+
// Expected output: "/loginreplacement"
143+
assertEquals("/loginreplacement", result);
144+
}
145+
146+
// No replacement when the substring is not found
147+
@Test
148+
public void testReplaceLast_NoMatch() {
149+
String input = "/login";
150+
String result = Utils.replaceLast(input, "/", "replacement");
151+
152+
// Expected output: "/login"
153+
assertEquals("replacementlogin", result);
154+
}
135155
}

dspace-server-webapp/src/main/java/org/dspace/app/rest/security/clarin/ClarinShibbolethLoginFilter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ protected void unsuccessfulAuthentication(HttpServletRequest request,
261261
String missingHeadersUrl = "missing-headers";
262262
String userWithoutEmailUrl = "auth-failed";
263263
String duplicateUser = "duplicate-user";
264+
String cannotAuthenticate = "shibboleth-authentication-failed";
264265

265266
// Compose the redirect URL
266267
if (this.isMissingHeadersFromIdp) {
@@ -270,6 +271,11 @@ protected void unsuccessfulAuthentication(HttpServletRequest request,
270271
} else if (StringUtils.isNotEmpty(this.netId)) {
271272
// netId is set if the user doesn't have the email
272273
redirectUrl += userWithoutEmailUrl + "?netid=" + this.netId;
274+
} else {
275+
// Remove the last slash from the URL `login/`
276+
String redirectUrlWithoutSlash = redirectUrl.endsWith("/") ?
277+
Utils.replaceLast(redirectUrl, "/", "") : redirectUrl;
278+
redirectUrl = redirectUrlWithoutSlash + "?error=" + cannotAuthenticate;
273279
}
274280

275281
response.sendRedirect(redirectUrl);

dspace-server-webapp/src/test/java/org/dspace/app/rest/security/ClarinShibbolethLoginFilterIT.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,18 @@ public void shouldNotAuthenticateOnSecondAttemptWithoutVerificationTokenInReques
658658
Util.formatNetId(netId, idp)));
659659
}
660660

661+
@Test
662+
public void shouldSendShibbolethAuthError() throws Exception {
663+
String idp = "Test Idp";
664+
665+
// Try to authenticate but the Shibboleth doesn't send the email or netid in the header,
666+
// so the user won't be registered but the user will be redirected to the login page with the error message.
667+
getClient().perform(get("/api/authn/shibboleth")
668+
.header("Shib-Identity-Provider", idp))
669+
.andExpect(status().isFound())
670+
.andExpect(redirectedUrl("http://localhost:4000/login?error=shibboleth-authentication-failed"));
671+
}
672+
661673
private EPerson checkUserWasCreated(String netIdValue, String idpValue, String email, String name)
662674
throws SQLException {
663675
// Check if was created a user with such email and netid.

0 commit comments

Comments
 (0)