2012-06-07 58 views
5

Cố gắng hiểu cách xác thực OpenID xác thực với Spring Security là cách chính xác.OpenID bảo mật mùa xuân - UserDetailsService, AuthenticationUserDetailsService

public class OpenIDUserDetailsService implements 
    UserDetailsService, 
    AuthenticationUserDetailsService { 

    @Override 
    public UserDetails loadUserByUsername(String openId) throws 
    UsernameNotFoundException, DataAccessException { 

    // I either want user email here 
    // or immediately delegate the request to loadUserDetails 

    } 

    @Override 
    public UserDetails loadUserDetails(Authentication token) throws 
    UsernameNotFoundException { 

    // This never gets called if I throw from loadUserByUsername() 

    } 

    private MyCustomUserDetails registerUser(String openId, String email) { 
    ... 
    } 
} 

Tôi đang xem xét kịch bản khi người dùng chưa đăng ký trong đơn đăng ký của mình. Để đăng ký người dùng, tôi cần biết OpenID và email của nó.

Khi nhà cung cấp OpenID chuyển hướng người dùng trở lại ứng dụng của tôi, loadUserByUsername() được gọi, nhưng trong trường hợp này tôi chỉ biết về OpenID của người dùng. Vì vậy, tôi đang ném UsernameNotFoundException và sau đó loadUserDetails() không bao giờ được gọi, vì vậy tôi không thể đăng ký người dùng.

Giải pháp phổ biến ở đây là gì? Nếu tôi trả lại một cái gì đó như FakePartialUserDetails từ loadUserByUsername() và sau đó, khi loadUserDetails() được gọi, tôi đăng ký người dùng và sau đó trả lại MyCustomUserDetails thực?

Tôi đang sử dụng Xuân An 3.0.7.RELEASE

Trả lời

1

Đó là buồn cười, nhưng quản lý để giải quyết nó bằng cách di chuyển đến Xuân An 3.1.0.RELEASE.

Đối với cùng một trường hợp, hành vi hoàn toàn khác nhau - loadUserByUsername() không được gọi và loadUserDetails() được gọi thay thế.

+4

Điều này không đúng. Trong 3.1, OpenIDAuthenticationProvider có các bộ định cư cho cả UserDetailsService và AuthenticationUserDetailsService và các lệnh gọi là loadUserByUsername hoặc loadUserDetails tùy thuộc vào setter nào được sử dụng. Trong 3.0.7, không có setter cho AuthenticationUserDetailsService và vì vậy nó luôn được sử dụng loadUserByUsername. – Ritesh

0

tôi giải quyết tình huống tương tự bằng cách thực hiện

AuthenticationUserDetailsService<OpenIDAuthenticationToken> 

trong UserDetailsService tôi.

public class OpenIdUserDetailsService implements UserDetailsService, 
    AuthenticationUserDetailsService<OpenIDAuthenticationToken> { 

@Autowired(required = true) 
@Qualifier(value = "jdbcUserDetailsService") 
private UserDetailsService localUserDetailsService; 

/** 
* @return the localUserDetailsService 
*/ 
public UserDetailsService getLocalUserDetailsService() { 
    return localUserDetailsService; 
} 

/** 
* @param localUserDetailsService 
*   the localUserDetailsService to set 
*/ 
public void setLocalUserDetailsService(
     UserDetailsService localUserDetailsService) { 
    this.localUserDetailsService = localUserDetailsService; 
} 

@Override 
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) 
     throws UsernameNotFoundException { 
    String email = getEmail(token); 
    return loadUserByUsername(email); 
} 

@Override 
public UserDetails loadUserByUsername(String username) 
     throws UsernameNotFoundException { 
    return localUserDetailsService.loadUserByUsername(username); 
} 

private String getEmail(OpenIDAuthenticationToken token) { 
    for (OpenIDAttribute attribute : token.getAttributes()) { 
     if (attribute.getName().equals("email")) { 
      return attribute.getValues().get(0); 
     } 
    } 
    return null; 
} 

} 

Chỉ cần đảm bảo sử dụng dịch vụ ở trên làm UserDetailsService trong khi định cấu hình biểu mẫu mở. Ngoài ra, cấu hình trao đổi thuộc tính cho thuộc tính 'email' trong khi định cấu hình openid. Email được trả lại sau khi xác thực thành công sau đó có thể được tìm nạp từ 'OpenIDAuthenticationToken' mà cuối cùng được chuyển thành tham số tới hàm loadUserByUsername.

Nếu bạn có người dùng đã đăng ký bằng email đó, quá trình xác thực hoàn tất. Khác bạn có thể đề nghị người dùng đăng ký bằng email đó hoặc hiển thị trang lỗi đăng nhập.

+0

Lý do thực sự cho OP được trả lời bởi Ritesh (bình luận cho câu trả lời được chấp nhận!) – manikanta

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