2013-01-02 30 views
7

Tôi đang sử dụng Bảo mật mùa xuân trong ứng dụng mùa xuân MVC của mình.Bảo mật mùa xuân bằng cả tên người dùng hoặc email

JdbcUserDetailsManager được khởi tạo với các truy vấn sau đây để xác thực:

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

Và cơ quan chức năng đang được nạp ở đây:

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

Tôi muốn làm cho nó để người dùng có thể đăng nhập với cả hai tên truy cập và e-mail. Có cách nào để sửa đổi hai truy vấn này để đạt được điều đó không? Hoặc là có một giải pháp tốt hơn?

Trả lời

4

Unfortunatelly không có cách nào dễ dàng làm điều này chỉ bằng cách thay đổi các truy vấn. Vấn đề là an ninh mùa xuân hy vọng rằng những người sử dụng-by-tên người dùng truy vấn và cơ quan chức năng theo tên người dùng truy vấn có một tham số duy nhất (tên người dùng) vì vậy nếu truy vấn của bạn chứa hai tham số như

username = ? or email = ? 

truy vấn sẽ thất bại .

gì bạn có thể làm, là thực hiện của riêng UserDetailsService rằng sẽ thực hiện các truy vấn (hoặc truy vấn) để tìm kiếm người dùng bằng tên đăng nhập hoặc e-mail và sau đó sử dụng thực hiện điều này như xác thực-nhà cung cấp trong cấu hình bảo mật mùa xuân của bạn như

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

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

Tôi đã xem lớp học nhưng có một chút rắc rối khi tìm ra phương pháp nào tôi nên ghi đè lên. Bất kỳ con trỏ? – tumanov

+1

Tôi nghĩ rằng tôi thấy nó bây giờ: loadUserByUsername (String username) – tumanov

1

Bạn có thể xác định các truy vấn tùy chỉnh trong các thuộc tính <jdbc-user-service> trong các thuộc tính users-by-username-queryauthorities-by-username-query tương ứng.

<jdbc-user-service data-source-ref="" users-by-username-query="" authorities-by-username-query=""/> 

Cập nhật

Bạn có thể tạo lớp mà thực hiện org.springframework.security.core.userdetails.UserDetailsService và cấu hình ứng dụng của bạn để sử dụng nó như một nguồn xác thực. Bên trong dịch vụ UserDetails tùy chỉnh của bạn, bạn có thể thực hiện các truy vấn mà bạn cần để có được người dùng từ cơ sở dữ liệu.

+0

Đó chính xác là những gì tôi đã làm và tôi đã đưa cả hai vào câu hỏi của mình. Vấn đề là tôi phải tùy chỉnh chúng để bao gồm cả tên người dùng và email. – tumanov

+0

Bạn chưa đề cập rằng bạn biết cách định cấu hình chúng. Và bạn đang hỏi "Có cách nào để sửa đổi hai truy vấn này để đạt được điều đó không?". –

+0

Dù sao tôi đã cập nhật câu trả lời của mình. –

2

Nếu tôi hiểu chính xác điều này, thì vấn đề là bạn muốn tra cứu tên người dùng do người dùng nhập vào trong hai cột DB khác nhau.

Chắc chắn, bạn có thể làm điều đó bằng cách tùy chỉnh UserDetailsService.

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 { 
       ....... 
      } 
     }); 
} 

Cấu hình bean của bạn cho lớp này sẽ trông giống như thế này.

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

truy vấn của bạn sẽ trông tương tự như sau

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

tôi đã cùng một vấn đề, và sau khi thử với rất nhiều câu hỏi khác nhau, với các thủ tục ... Tôi thấy rằng hoạt động này:

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 của nó st lặp lại cấu hình với hai truy vấn.

Các vấn đề liên quan