Да, можно использовать обычную аутентификацию, а также аутентификацию OAuth2, но я сомневаюсь, что вы сможете легко установить ее, так как метод authenticated()
HttpSecurity не позволяет вам выбрать, какая из ваших аутентификаций метод (oauth2Login / formLogin) будет работать.
Однако есть способ легко обойти это:
Вы можете добавить пользовательские права доступа, назовем их ROLE_BASICAUTH
, когда пользователь подключается с использованием базовой аутентификации, и ROLE_OAUTH2
, когда пользователь подключается с использованием OAuth2. Таким образом, вы можете использовать
.antMatchers("/endpoint-that-requires-basic-auth").hasRole("BASICAUTH")
.antMatchers("/endpoint-that-requires-oauth2").hasRole("OAUTH2")
.anyRequest().authenticated()
Когда они достигают конечной точки, для которой требуется базовая аутентификация (а не OAuth2), вы проверяете их текущие полномочия, и если это не BASICAUTH
, тогда вы аннулируете их сеанс, вы отображаете форму входа без OAuth2 (чтобы заставить их использовать базовую аутентификацию).
Недостатком этого является то, что вам нужно реализовать как пользовательский UserDetailsService
, так и пользовательский OAuth2UserService
...
Но на самом деле это не так сложно:
@Service
public class UserService extends DefaultOAuth2UserService implements UserDetailsService {
// ...
@Override
public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
OAuth2User user = super.loadUser(oAuth2UserRequest);
Map<String, Object> attributes = user.getAttributes();
Set<GrantedAuthority> authoritySet = new HashSet<>(user.getAuthorities());
String userNameAttributeName = oAuth2UserRequest.getClientRegistration().getProviderDetails()
.getUserInfoEndpoint().getUserNameAttributeName();
authoritySet.add(new SimpleGrantedAuthority("ROLE_OAUTH2"));
return new DefaultOAuth2User(authoritySet, attributes, userNameAttributeName);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = getUserFromDatabase(username); // you'll need to provide that method (where are the username/password stored?)
if (user == null) { // UserDetailsService doesn't allow loadUserByUsername to return null, so throw exception
throw new UsernameNotFoundException("Couldn't find user with username '"+username+"'");
}
// add ROLE_BASICAUTH (you might need a custom UserDetails implementation here, because by defaut, UserDetails.getAuthorities() is immutable (I think, I might be a liar)
return user;
}
}
Обратите внимание, что это грубая реализация, поэтому вам также придется немного поработать над ней.
Вы также можете использовать этот репозиторий, который я создал https://github.com/TwinProduction/spring-security-oauth2-client-example/tree/master/custom-userservice-sample в качестве руководства для пользовательского OAuth2UserService
Удачи.