【问题标题】:Handle BadCredentialsException throwned in Spring Security's Authentication Provider处理 Spring Security Authentication Provider 中抛出的 BadCredentialsException
【发布时间】:2017-07-11 02:06:46
【问题描述】:

我正在使用 Spring-MVC 和 Spring-Security 开发 Web 应用程序。

我正在使用带有 AuthenticationProvider 的自定义登录,而 AuthenticationProvider 又使用 UserDetailsS​​ervice 将登录表单中的数据与数据库中的数据进行匹配。

我想在 AuthenticationProvider 中抛出 2 个异常,第一个是用户名不存在于数据库中,另一个是密码不同时。

我想做的是在我的网页中显示抛出异常的错误消息(错误的用户名或错误的密码),但我不知道在哪里使用 catch 块,因为登录流是受管理的由 Spring-Security 提供

身份验证提供者

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    CustomUserDetailsService userDetails;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        Customer customer = userDetails.loadUserByUsername(username);

        if(customer == null) {
            throw new BadCredentialsException("Wrong username");
        }

        if(!password.equals(customer.getPassword())) {
            throw new BadCredentialsException("Wrong password");
        }

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(customer.getRole()));

        return new UsernamePasswordAuthenticationToken(customer, password, authorities);
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return clazz.equals(UsernamePasswordAuthenticationToken.class);
    }
}

登录页面

[...]
<div class="form">
    <h2>Login</h2>
    <form th:action="@{/login}" method="POST" th:object="${customer}">
        <input type="text" placeholder="Username" name="username" th:field="*{username}"/> 
        <input type="password" placeholder="Password" name="password" th:field="*{password}"/>
        <button type="submit">Login</button>
    </form>
</div>
[...]

spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <http pattern="/resources/**" security="none" />

    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/user/**" access="hasRole('USER')" />
        <form-login authentication-failure-url="/login" login-page="/login"
            login-processing-url="/login" default-target-url="/user" />
        <logout invalidate-session="true" success-handler-ref="logoutSuccessHandler" />
    </http>

    <authentication-manager>
        <authentication-provider ref="customAuthenticationProvider" />
    </authentication-manager>
</beans:beans>

【问题讨论】:

    标签: java authentication spring-security exception-handling


    【解决方案1】:

    使用 Thymeleaf 时,您可以像这样“捕获”身份验证异常:

    <p th:if="${param.error != null and session['SPRING_SECURITY_LAST_EXCEPTION'] != null}"
       th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message}">
      Wrong username or password
    </p>
    

    您可能可以使用标准的DaoAuthenticationProvider 而不是自定义类:

    @Bean
    public DaoAuthenticationProvider customAuthenticationProvider()
    {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setHideUserNotFoundExceptions(false);
        return provider;
    }
    

    注意,一般不建议在认证失败时判断用户名是否存在于系统中。

    【讨论】:

    • 正如我所见,他没有在 CustomAuthenticationProvider 中的 userDetailsS​​ervice 中抛出异常,而是在 CustomAuthenticationProvider 中执行所有逻辑,并且他希望在提供者中抛出不同的错误消息,那么如何在 thymeleaf 中看到错误文本他的案子?
    猜你喜欢
    • 2023-02-10
    • 1970-01-01
    • 2016-03-02
    • 2022-10-04
    • 1970-01-01
    • 2012-05-19
    • 2015-07-03
    • 2023-04-04
    • 2013-09-01
    相关资源
    最近更新 更多