Spring microservices с OAuth2- ResourceServer возвращает только String в качестве принципала, а не моего пользовательского пользователя - PullRequest
0 голосов
/ 25 июня 2018

У меня есть два микросервиса, один из которых настроен как сервер 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?

Спасибо за помощь:)

1 Ответ

0 голосов
/ 27 июня 2018

Ну, возвращать объект Principal не стоит (скорее всего, это будет класс его реализации UsernamePasswordAuthenticationToken). Если вы хотите, чтобы конечная точка предоставляла только пользовательские данные, предпочтительным способом было бы создать объект передачи данных, содержащий только ту информацию, которую вы хотите предоставить.

Рекомендуемый способ получения принципала (аутентифицированного пользователя, который делает запрос) из контекста безопасности. Более подробная информация об этом доступна здесь .

...