* Prevents SSO login due to faulty verification * add translation & fix show error message * Update settings.yml.template --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
This commit is contained in:
@@ -2,8 +2,8 @@ package stirling.software.SPDF.config.security.oauth2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.LockedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
@@ -13,19 +13,34 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class CustomOAuth2AuthenticationFailureHandler
|
||||
extends SimpleUrlAuthenticationFailureHandler {
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(CustomOAuth2AuthenticationFailureHandler.class);
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailure(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException exception)
|
||||
throws IOException, ServletException {
|
||||
|
||||
if (exception instanceof BadCredentialsException) {
|
||||
log.error("BadCredentialsException", exception);
|
||||
getRedirectStrategy().sendRedirect(request, response, "/login?error=badcredentials");
|
||||
return;
|
||||
}
|
||||
if (exception instanceof DisabledException) {
|
||||
log.error("User is deactivated: ", exception);
|
||||
getRedirectStrategy().sendRedirect(request, response, "/logout?userIsDisabled=true");
|
||||
return;
|
||||
}
|
||||
if (exception instanceof LockedException) {
|
||||
log.error("Account locked: ", exception);
|
||||
getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked");
|
||||
return;
|
||||
}
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2Error error = ((OAuth2AuthenticationException) exception).getError();
|
||||
|
||||
@@ -34,17 +49,13 @@ public class CustomOAuth2AuthenticationFailureHandler
|
||||
if (error.getErrorCode().equals("Password must not be null")) {
|
||||
errorCode = "userAlreadyExistsWeb";
|
||||
}
|
||||
logger.error("OAuth2 Authentication error: " + errorCode);
|
||||
log.error("OAuth2 Authentication error: " + errorCode);
|
||||
log.error("OAuth2AuthenticationException", exception);
|
||||
getRedirectStrategy()
|
||||
.sendRedirect(request, response, "/logout?erroroauth=" + errorCode);
|
||||
return;
|
||||
} else if (exception instanceof LockedException) {
|
||||
logger.error("Account locked: ", exception);
|
||||
getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked");
|
||||
return;
|
||||
} else {
|
||||
logger.error("Unhandled authentication exception", exception);
|
||||
super.onAuthenticationFailure(request, response, exception);
|
||||
}
|
||||
log.error("Unhandled authentication exception", exception);
|
||||
super.onAuthenticationFailure(request, response, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@ package stirling.software.SPDF.config.security.oauth2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.LockedException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
@@ -26,9 +25,6 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
||||
|
||||
private LoginAttemptService loginAttemptService;
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(CustomOAuth2AuthenticationSuccessHandler.class);
|
||||
|
||||
private ApplicationProperties applicationProperties;
|
||||
private UserService userService;
|
||||
|
||||
@@ -46,6 +42,17 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
||||
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws ServletException, IOException {
|
||||
|
||||
Object principal = authentication.getPrincipal();
|
||||
String username = "";
|
||||
|
||||
if (principal instanceof OAuth2User) {
|
||||
OAuth2User oauthUser = (OAuth2User) principal;
|
||||
username = oauthUser.getName();
|
||||
} else if (principal instanceof UserDetails) {
|
||||
UserDetails oauthUser = (UserDetails) principal;
|
||||
username = oauthUser.getUsername();
|
||||
}
|
||||
|
||||
// Get the saved request
|
||||
HttpSession session = request.getSession(false);
|
||||
String contextPath = request.getContextPath();
|
||||
@@ -59,11 +66,8 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
||||
// Redirect to the original destination
|
||||
super.onAuthenticationSuccess(request, response, authentication);
|
||||
} else {
|
||||
OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal();
|
||||
OAUTH2 oAuth = applicationProperties.getSecurity().getOAUTH2();
|
||||
|
||||
String username = oauthUser.getName();
|
||||
|
||||
if (loginAttemptService.isBlocked(username)) {
|
||||
if (session != null) {
|
||||
session.removeAttribute("SPRING_SECURITY_SAVED_REQUEST");
|
||||
@@ -78,15 +82,21 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
||||
&& oAuth.getAutoCreateUser()) {
|
||||
response.sendRedirect(contextPath + "/logout?oauth2AuthenticationErrorWeb=true");
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
userService.processOAuth2PostLogin(username, oAuth.getAutoCreateUser());
|
||||
response.sendRedirect(contextPath + "/");
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
|
||||
}
|
||||
try {
|
||||
if (oAuth.getBlockRegistration()
|
||||
&& !userService.usernameExistsIgnoreCase(username)) {
|
||||
response.sendRedirect(contextPath + "/logout?oauth2_admin_blocked_user=true");
|
||||
return;
|
||||
}
|
||||
if (principal instanceof OAuth2User) {
|
||||
userService.processOAuth2PostLogin(username, oAuth.getAutoCreateUser());
|
||||
}
|
||||
response.sendRedirect(contextPath + "/");
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,34 +2,26 @@ package stirling.software.SPDF.config.security.oauth2;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||
import stirling.software.SPDF.model.Provider;
|
||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
||||
import stirling.software.SPDF.utils.UrlUtils;
|
||||
|
||||
@Slf4j
|
||||
public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(CustomOAuth2LogoutSuccessHandler.class);
|
||||
|
||||
private final SessionRegistry sessionRegistry;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public CustomOAuth2LogoutSuccessHandler(
|
||||
ApplicationProperties applicationProperties, SessionRegistry sessionRegistry) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
public CustomOAuth2LogoutSuccessHandler(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@@ -42,6 +34,15 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
||||
String issuer = null;
|
||||
String clientId = null;
|
||||
|
||||
if (authentication == null) {
|
||||
if (request.getParameter("userIsDisabled") != null) {
|
||||
response.sendRedirect(
|
||||
request.getContextPath() + "/login?erroroauth=userIsDisabled");
|
||||
} else {
|
||||
super.onLogoutSuccess(request, response, authentication);
|
||||
}
|
||||
return;
|
||||
}
|
||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
||||
|
||||
if (authentication instanceof OAuth2AuthenticationToken) {
|
||||
@@ -53,9 +54,8 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
||||
issuer = provider.getIssuer();
|
||||
clientId = provider.getClientId();
|
||||
} catch (UnsupportedProviderException e) {
|
||||
logger.error(e.getMessage());
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
|
||||
} else {
|
||||
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
|
||||
issuer = oauth.getIssuer();
|
||||
@@ -70,18 +70,16 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
||||
param = "erroroauth=" + sanitizeInput(errorMessage);
|
||||
} else if (request.getParameter("oauth2AutoCreateDisabled") != null) {
|
||||
param = "error=oauth2AutoCreateDisabled";
|
||||
} else if (request.getParameter("oauth2_admin_blocked_user") != null) {
|
||||
param = "erroroauth=oauth2_admin_blocked_user";
|
||||
} else if (request.getParameter("userIsDisabled") != null) {
|
||||
param = "erroroauth=userIsDisabled";
|
||||
} else if (request.getParameter("badcredentials") != null) {
|
||||
param = "error=badcredentials";
|
||||
}
|
||||
|
||||
String redirect_url = UrlUtils.getOrigin(request) + "/login?" + param;
|
||||
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
String sessionId = session.getId();
|
||||
sessionRegistry.removeSessionInformation(sessionId);
|
||||
session.invalidate();
|
||||
logger.info("Session invalidated: " + sessionId);
|
||||
}
|
||||
|
||||
switch (registrationId.toLowerCase()) {
|
||||
case "keycloak":
|
||||
// Add Keycloak specific logout URL if needed
|
||||
@@ -92,13 +90,13 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
||||
+ clientId
|
||||
+ "&post_logout_redirect_uri="
|
||||
+ response.encodeRedirectURL(redirect_url);
|
||||
logger.info("Redirecting to Keycloak logout URL: " + logoutUrl);
|
||||
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
|
||||
response.sendRedirect(logoutUrl);
|
||||
break;
|
||||
case "github":
|
||||
// Add GitHub specific logout URL if needed
|
||||
String githubLogoutUrl = "https://github.com/logout";
|
||||
logger.info("Redirecting to GitHub logout URL: " + githubLogoutUrl);
|
||||
log.info("Redirecting to GitHub logout URL: " + githubLogoutUrl);
|
||||
response.sendRedirect(githubLogoutUrl);
|
||||
break;
|
||||
case "google":
|
||||
@@ -106,13 +104,14 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
||||
// String googleLogoutUrl =
|
||||
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
|
||||
// + response.encodeRedirectURL(redirect_url);
|
||||
// logger.info("Redirecting to Google logout URL: " + googleLogoutUrl);
|
||||
log.info("Google does not have a specific logout URL");
|
||||
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
|
||||
// response.sendRedirect(googleLogoutUrl);
|
||||
// break;
|
||||
default:
|
||||
String redirectUrl = request.getContextPath() + "/login?" + param;
|
||||
logger.info("Redirecting to default logout URL: " + redirectUrl);
|
||||
response.sendRedirect(redirectUrl);
|
||||
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
|
||||
log.info("Redirecting to default logout URL: " + defaultRedirectUrl);
|
||||
response.sendRedirect(defaultRedirectUrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user