У меня есть два микросервиса, один из которых настроен как сервер OAuth2 - A, а другой - как клиент OAuth2 - B. Я хотел бы поделиться своим пользовательским пользователем между этими двумя микросервисами.Когда пользователь идентифицирует себя с помощью AI, создает пользовательскую реализацию UserDetails, я хотел бы защитить некоторые ресурсы в B. Так что я настроил сервер ресурсов, который совпадает с A. Я ожидал, что смогу поделиться своей пользовательской реализацией UserDetails междуА и Б с использованием принципала.Я могу получить пользовательский пользователь от принципала в A, но в B принципал представлен только String (имя пользователя).Как я могу заставить сервер ресурсов возвращать пользовательскую реализацию UserDetails, а не только имя пользователя?
источник A-сервера
Конфигурация сервера:
@SpringBootApplication
@EnableResourceServer
@EnableAuthorizationServer
@EnableWebSecurity
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Реализация UserDetailsService, которая возвращает мой CustomUser, который реализует UserDetails (просто фиктивный для простоты)
@Service
@Primary
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
GrantedAuthority authority = new Authority("USER");
return new CustomUser(5L, "username", "{noop}password", Arrays.asList(authority));
}
}
Конфигурация сервера OAuth2:
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("user")
.secret("{noop}password")
.authorizedGrantTypes("password", "refresh_token")
.scopes("webapp");
}
}
WebSecurityConfigurerAdapter:
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
Вот как принципал «должен» быть доступным для других сервисов, через конечную точку покоя, которая возвращает просто Принципал, здесь в сервисе A он содержит экземпляр CustomUser:
@RestController
@RequestMapping("/user")
public class UserRestController {
@GetMapping("/auth")
public Principal getPrincipal(Principal principal) {
return principal;
}
}
Клиент источник B - клиент
Application.properties - URL конечной точки из A
server.port=8081
security.oauth2.resource.user-info-uri=http://localhost:8080/user/auth
стартер B
@SpringBootApplication
@EnableResourceServer
@EnableWebSecurity
@EnableOAuth2Client
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
И, наконец, контроллер остальных,Я использую, чтобы проверить, является ли принципал строка (имя пользователя) или CustomUser.К сожалению, принципал всегда содержит только имя пользователя и карту полей со значениями от пользовательского пользователя.
@RestController
@RequestMapping("/client")
public class ClientRestController {
@GetMapping("/print")
public void printId(Principal principal) {
System.out.println(principal);
}
}
Не могли бы вы помочь мне решить эту проблему?Как я могу передать Принципал с моим CustomUser?
Спасибо за помощь:)