2

私はSpringにかなり慣れていません。

私の目標は、ユーザー名とパスワードだけでなく、オブジェクトを引数として受け取るAuthenticationProviderカスタムauthenticateメソッドを使用することです。Authenticateレルム名としましょう (異なるレルムにいる場合、同じユーザー名を持つ 2 人のユーザーが存在する可能性があります)。私はすでに私の質問への回答を探していましたが、認証に関する質問への簡単な回答は拡張する方法のみを説明してAbstractUserDetailsAuthenticationProviderいます。ユーザーを取得します。複雑なものは、コンテキストを説明せずに、あらゆる種類の異なる Spring クラスとインターフェースを拡張または実装することに関するものです。

簡単な質問は次のとおりです。

AuthenticationProviderオブジェクトからカスタム データを読み取れるようにするには、どのように実装/拡張する必要がありAuthenticationますか?

私の呼び出しは次のようになります (はい、OAuth2 トークンを取得したいです):

curl -vX POST http://localhost:9001/oauth/token \
-d "client_id=myId&client_secret=secret&grant_type=password&username=myUser&password=1234&realm=realm3"

realm=realm3末尾に注意してください。

余分なデータを使用せず、独自のサブクラスを使用した呼び出しは、AbstractUserDetailsAuthenticationProviderレルムが 1 つしかない場合でも既に機能しています。

前もって感謝します!

4

1 に答える 1

1

AuthenticationProvider を実装/拡張して、Authentication オブジェクトからカスタム データを読み取るにはどうすればよいですか?

RealmAuthenticationProvider

public class RealmAuthenticationProvider implements AuthenticationProvider {

    private RUPAuthenticator rupAuthenticator;

    public RealmAuthenticationProvider(RUPAuthenticator rupAuthenticator) {
        this.rupAuthenticator = rupAuthenticator;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        Object principal = authentication.getPrincipal();
        Object credentials = authentication.getCredentials();
        Object realm = authentication.getDetails();
        if (rupAuthenticator.authenticate(principal, credentials, realm)) {
            List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
            grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); //use any GrantedAuthorities you need
            return new RealmAuthenticationToken(principal, credentials, realm, grantedAuths);
        };
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return RealmAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

RealmAuthenticationToken

public class RealmAuthenticationToken extends UsernamePasswordAuthenticationToken {

    private Object realm;

    public RealmAuthenticationToken(Object principal, Object credentials, Object realm, Collection<? extends GrantedAuthority> authorities) {
        super(principal,credentials, authorities);
        this.realm = realm;
    }
}

RUPAuthenticator

public interface RUPAuthenticator {
    boolean authenticate(Object username, Object password, Object realm);
}

ユーザー名、パスワード、レルムの組み合わせが正しいかどうかを示す RUPAuthenticator の実装を提供するだけで済みます。

そして、カスタム AuthenticationProvider (RealmAuthenticationProvider) を Bean として登録します。以下は、特定のユーザーからの要求を受け入れる認証プロバイダーの例です。

@Bean
public AuthenticationManager authenticationManager() {
        List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
        providers.add(new RealmAuthenticationProvider(new RUPAuthenticator() {
            @Override
            public boolean authenticate(Object username, Object password, Object realm) {
                return (username.equals("sa") && password.equals("sa") && realm.equals("realm2"));
            }
        }));
        return new ProviderManager(providers);
    }

これがあなたが探していたものであることを願っています。

于 2014-05-02T19:04:31.777 に答える