2

我对春天很陌生。

我的目标是有一些AuthenticationProvider带有自定义authenticate方法的方法,该方法将Authenticate对象作为参数,而不仅仅是用户名和密码。假设一个领域名称(当他们在不同领域时,可以有 2 个具有相同用户名的用户)。我已经在寻找我的问题的答案,但是关于身份验证问题的简单答案只解释了如何扩展AbstractUserDetailsAuthenticationProvider,这不能满足我的需要,因为检索方法只将用户名作为参数,而我也需要域名来检索用户。复杂的是在没有解释上下文的情况下扩展或实现各种不同的 Spring 类和接口。

所以简单的问题是:

我如何实现/扩展 anAuthenticationProvider才能从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当只有一个领域时,没有额外数据和我自己的子类的调用已经有效。

提前致谢!

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

RUP身份验证器

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