Я новичок в Spring.
Моя цель состоит в том, чтобы иметь некоторый AuthenticationProvider
с настраиваемым методом authenticate
который принимает объект Authenticate
как аргумент с более чем просто именем пользователя и паролем. Позвольте сказать имя области (и могут быть 2 пользователя с тем же именем пользователя, когда они находятся в разных сферах). Я уже искал ответы на свой вопрос, но простые ответы на вопросы об аутентификации объясняют, как расширить AbstractUserDetailsAuthenticationProvider
, который не удовлетворяет мои потребности, потому что метод retrieve принимает имя пользователя как аргумент, в то время как мне также требуется имя области для извлечения пользователя. Сложные из них касаются расширения или реализации всех видов различных классов и интерфейсов 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
уже работает, когда существует только одна область.
Заранее спасибо!
Как мне реализовать/расширить 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
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);
}
Надеюсь, это то, что вы искали.