Spring Security使用用户名或电子邮件

tum*_*nov 8 authentication spring spring-mvc spring-security

我在Spring MVC应用程序中使用Spring Security .

JdbcUserDetailsManager 使用以下查询进行初始化以进行身份​​验证:

select username, password, enabled from user where username = ?
Run Code Online (Sandbox Code Playgroud)

当局正在加载:

select u.username, a.authority from user u join authority a on u.userId = a.userId where username = ?
Run Code Online (Sandbox Code Playgroud)

我想这样做,以便用户可以使用用户名和电子邮件登录.有没有办法修改这两个查询来实现?还是有更好的解决方案?

dim*_*ies 5

不幸的是,仅仅通过更改查询没有简单的方法来做到这一点。问题是 spring security 期望 users-by-username-query 和 authority-by-username-query 有一个参数(用户名),所以如果你的查询包含两个参数,比如

username = ? or email = ?
Run Code Online (Sandbox Code Playgroud)

查询将失败。

您可以做的是实现您自己的UserDetailsS​​ervice,它将执行查询(或查询)以通过用户名或电子邮件搜索用户,然后将此实现用作您的 spring 安全配置中的身份验证提供程序,例如

  <authentication-manager>
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>

  <beans:bean id="myUserDetailsService" class="xxx.yyy.UserDetailsServiceImpl">
  </beans:bean>
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到了同样的问题,在尝试了很多不同的查询后,程序......我发现这有效:

public void configAuthentication(AuthenticationManagerBuilder auth)
        throws Exception {
    // Codificación del hash
    PasswordEncoder pe = new BCryptPasswordEncoder();

    String userByMailQuery = "SELECT mail, password, enabled FROM user_ WHERE mail = ?;";
    String userByUsernameQuery = "SELECT mail, password, enabled FROM user_ WHERE username=?";
    String roleByMailQuery = "SELECT mail, authority FROM role WHERE mail =?;";

    auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(pe)
            .usersByUsernameQuery(userByMailQuery)
            .authoritiesByUsernameQuery(roleByMailQuery);

    auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(pe)
            .usersByUsernameQuery(userByUsernameQuery)
            .authoritiesByUsernameQuery(roleByMailQuery);

}
Run Code Online (Sandbox Code Playgroud)

它只是用两个查询重复配置。