5

SpringSecurityでOpenID認証を実装する正しい方法を理解しようとしています。

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

ユーザーがまだアプリケーションに登録されていないシナリオを検討しています。ユーザーを登録するには、OpenIDとメールアドレスを知っている必要があります。

OpenIDプロバイダーがユーザーをアプリケーションにリダイレクトするloadUserByUsername()と、が呼び出されますが、この場合、私はユーザーのOpenIDについてのみ認識しています。だから、投げUsernameNotFoundExceptionloadUserDetails()電話がかかってこないので、ユーザーを登録できません。

ここでの一般的な解決策は何ですか?FakePartialUserDetailsfromのようなものを返し、が呼び出されloadUserByUsername()たときloadUserDetails()にユーザーを登録してから実際のを返すとどうなりMyCustomUserDetailsますか?

SpringSecurity3.0.7.RELEASEを使用しています

4

2 に答える 2

1

それは面白いですが、SpringSecurity3.1.0.RELEASEに移行することで解決できました。

同じシナリオの場合、動作はまったく異なります。呼び出されloadUserByUsername()ず、loadUserDetails()代わりに呼び出されます。

于 2012-06-07T08:09:39.123 に答える
0

実装することで同じ状況を解決しました

AuthenticationUserDetailsService<OpenIDAuthenticationToken>

私のUserDetailsS​​erviceで。

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

}

openid-formを構成するときは、必ず上記のサービスをUserDetailsS​​erviceとして使用してください。また、openidを構成するときに、「email」属性の属性交換を構成します。認証が成功した後に返される電子メールは、「OpenIDAuthenticationToken」からフェッチでき、最終的にはパラメーターとしてloadUserByUsername関数に渡されます。

その電子メールにユーザーを登録している場合、認証は完了です。それ以外の場合は、その電子メールで登録するか、ログイン失敗ページを表示するようにユーザーに提案できます。

于 2013-05-15T17:44:52.667 に答える