2013-01-02 66 views
7

我在我的Spring MVC應用程序中使用Spring Security。春季安全使用用戶名或電子郵件

JdbcUserDetailsManager與下面的查詢初始化認證:

select username, password, enabled from user where username = ? 

和當局正在這裏下載:

select u.username, a.authority from user u join authority a on u.userId = a.userId where username = ? 

我想使它這樣用戶可以使用包含用戶名登錄,電子郵件。有沒有辦法修改這兩個查詢來實現?還是有更好的解決方案?

回答

4

不幸的是,僅僅通過改變查詢就沒有簡單的方法。問題是Spring Security預計,用戶按用戶名查詢和部門按用戶名查詢只有一個參數(用戶名),所以如果您的查詢包含類似

username = ? or email = ? 

兩個參數的查詢將失敗。

你可以做什麼,是實現自己的的UserDetailsS​​ervice將執行查詢(或查詢)的用戶名或電子郵件搜索用戶,然後用這個實現的認證供應商在你的春季安全配置像

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

    <beans:bean id="myUserDetailsService" class="xxx.yyy.UserDetailsServiceImpl"> 
    </beans:bean> 
+0

我已經看過這個類,但是在確定應該覆蓋哪些方法時遇到了一些問題。任何指針? – tumanov

+1

我想我現在看到它:loadUserByUsername(String username) – tumanov

1

您可以分別在users-by-username-queryauthorities-by-username-query屬性中分別定義<jdbc-user-service>標記中的自定義查詢。

​​

更新

您可以創建類,它實現org.springframework.security.core.userdetails.UserDetailsService和配置您的應用程序使用它作爲身份驗證源。在您的自定義UserDetails服務中,您可以執行從數據庫獲取用戶所需的查詢。

+0

這正是我一直在做的事情,我已經將他們都包括在我的問題中。問題是我必須定製它們以包括用戶名和電子郵件。 – tumanov

+0

你還沒有提到你知道如何配置它們。而且你問:「有沒有辦法修改這兩個查詢來實現?」。 –

+0

無論如何,我已經更新了我的答案。 –

2

如果我正確地理解了這個問題,那麼問題在於您希望查找用戶在兩個不同的DB列中輸入的用戶名。

當然,你可以通過自定義UserDetailsS​​ervice來做到這一點。

public class CustomJdbcDaoImpl extends JdbcDaoImpl { 

    @Override 
    protected List<GrantedAuthority> loadUserAuthorities(String username) { 
    return getJdbcTemplate().query(getAuthoritiesByUsernameQuery(), new String[] {username, username}, new RowMapper<GrantedAuthority>() { 
      public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException { 
       ....... 
      } 
     }); 
    } 

    @Override 
    protected List<UserDetails> loadUsersByUsername(String username) { 
     return getJdbcTemplate().query(getUsersByUsernameQuery(), new String[] {username, username}, new RowMapper<UserDetails>() { 
      public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException { 
       ....... 
      } 
     }); 
} 

這個類的bean配置看起來像這樣。

<beans:bean id="customUserDetailsService" class="com.xxx.CustomJdbcDaoImpl"> 
    <beans:property name="dataSource" ref="dataSource"/> 
    <beans:property name="usersByUsernameQuery"> 
     <beans:value> YOUR_QUERY_HERE</beans:value> 
    </beans:property> 
    <beans:property name="authoritiesByUsernameQuery"> 
     <beans:value> YOUR_QUERY_HERE</beans:value> 
    </beans:property> 
</beans:bean> 

您的查詢將類似於此

select username, password, enabled from user where (username = ? or email = ?) 
select u.username, a.authority from user u join authority a on u.userId = a.userId where (username = ? or email = ?) 
2

我有同樣的問題的東西,並且有很多不同的查詢的努力,用手續後...我發現此作品:

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); 

} 

其ju st用兩個查詢重複配置。

相關問題