Florent Biville (Migrated from SEC-2701) said:
Hi, it seems that DaoAuthenticationProvider#retrieveUser semantics have changed since 3.0.x.
Indeed, DaoAuthenticationProvider was catching only some particular exceptions back then, thus propagating the other ones possibly thrown by the configured UserDetailsService.
In 3.0.x, this (ugly) logic works:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<div id="form_login">
<c:choose>
<c:when test="${not empty param.error}">
<div><label class="error"><strong>
<c:if test="${fn:indexOf(sessionScope.SPRING_SECURITY_LAST_EXCEPTION.class, 'BadCredentialsException') != -1}">
<p>Identifiant et/ou mot de passe incorrect(s).</p>
</c:if>
<c:if test="${fn:indexOf(sessionScope.SPRING_SECURITY_LAST_EXCEPTION.class, 'AccountExpiredException') != -1}">
<p>L'application ne peut pas fonctionner : la licence est invalide ou inexistante. <br/>
Veuillez contacter votre administrateur.</p>
</c:if>
<c:if test="${fn:indexOf(sessionScope.SPRING_SECURITY_LAST_EXCEPTION.class, 'AuthenticationCredentialsNotFoundException') != -1}">
<p>Votre raccourci de connexion est invalide.<br/>
Veuillez contacter votre administrateur.</p>
</c:if>
<c:if test="${fn:indexOf(sessionScope.SPRING_SECURITY_LAST_EXCEPTION.class, 'LockedException') != -1}">
<p>Opération interdite !</p>
</c:if>
<c:if test="${param.error == '2' || fn:indexOf(sessionScope.SPRING_SECURITY_LAST_EXCEPTION.class, 'SessionAuthenticationException') != -1}">
<p>Vous avez atteint le nombre maximum de connexions simultanées.</p>
</c:if>
</strong></label></div>
</c:when>
</c:choose>
<form name='form_login' action="<c:url value='/j_spring_security_check'/>" method='POST'>
<div class="left">Identifiant :</div><div id="input_ident" class="input_form_login" align="left"><input border="0" class="zone_texte" id='identifiant' type='text' name='j_username' tabindex="1" /></div>
<div class="left">Mot de passe :</div><div id="input_mdp" class="input_form_login" align="left"><input border="0" class="zone_texte" type='password' name='j_password' tabindex="2" /></div>
<div id="check_box_form"><input id="remember_me" type="checkbox" value="1" checked tabindex="3" name="_spring_security_remember_me" />Mémoriser vos informations sur cet ordinateur</div>
<div id="bouton_ident" align="center"><input class="bouton_submit_login" id="bouton submit" name="submit" type="submit" value="S'identifier" tabindex="4" /></div>
</form>
</div>
In 3.1.x (and 3.2.x I believe), all exceptions thrown by the configured UserDetailsService are shadowed by the catch Exception block and the above logic becomes ineffective as the only visible exception is an instance of AuthenticationServiceException.
What do you recommend here? Rely on exception message rather than type? Or should the exception catch be changed?
Comment From: akcanmuhammet
this issue still remains when throwing custom exceptions from UserDetailsService DaoAuthenticationProvider catches it and throws InternalAuthenticationServiceException therefore thrown exception of UserDetailsService is lost.
Here is the exact line which causes the problem: https://github.com/spring-projects/spring-security/blob/main/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java#L135
I think catching of exceptions must be more specific