Я исследую микросервисную архитектуру. Я выбрал весенний облачный каркас.
Схема моего приложения выглядит так:
Также у меня есть сервер обнаружения eureka, но я решил пропустить картинку, чтобы упростить ее.
Полный исходный код примера вы можете найти на гитибе: https://github.com/gredwhite/spring-cloud
привет мировой сервис:
@GetMapping("/helloWorld")
@HystrixCommand(fallbackMethod = "reliable")
public String hello() {
return this.restTemplate.getForObject("http://hello-service/hello?name=World", String.class);
}
привет сервис:
@GetMapping("/hello")
public String hello(@RequestParam("name") String name) throws UnknownHostException, InterruptedException {
return "Hello " + name + "!";
}
Когда я запустил hello service и попытался получить доступ к localhost:8082/h/hello?name=Vasya (/h - контекстный путь) - запрос выполняется успешно, и я вижу сообщение Hello Vasya в ответе. Я должен сказать, что для этой службы отключена аутентификация.
hello world service имеет страницу index.html, и когда я пытаюсь получить к ней доступ, процесс аутентификации выполняется успешно, и в конечном итоге это приложение успешно входит в систему. Затем я пытаюсь выполнить метод /hello из hello world service и вижу ответ:
{"timestamp":"2018-05-17T08:53:04.623+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/hw/helloWorld"}
привет мировой сервис
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "say-hello")
@EnableAutoConfiguration
@EnableOAuth2Sso
public class HelloWorldStarter {
public static void main(String[] args) {
SpringApplication.run(HelloWorldStarter.class, args);
}
@RestController
@EnableDiscoveryClient
@EnableCircuitBreaker
public static class HelloWorldController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/helloWorld")
@HystrixCommand(fallbackMethod = "reliable")
public String hello() {
return this.restTemplate.getForObject("http://hello-service/hello?name=World", String.class);
}
public String reliable() {
return "Could not get response from service";
}
}
@org.springframework.context.annotation.Configuration
public static class Configuration {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
}
application.yml:
spring:
application:
name: hello-world-service
server:
port: 8081
servlet:
context-path: /hw
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
instance:
preferIpAddress: true
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
logging:
level:
org.springframework.security: DEBUG
org.springframework.web: DEBUG
hello world service.



Я считаю, что вы используете очень странный подход к решению своей проблемы.
Предлагаю вам следующее решение:
@FeignClient(name = "hello-service", url = "http://hello-service")
public interface HelloService {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
String hello(@PathVariable("name") String name);
}@Bean
public RequestInterceptor oauth2FeignRequestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
requestTemplate.header("Authorization", "bearer " + details.getTokenValue());
}
};
}@EnableOAuth2Client
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableFeignClients
public class HelloWorldStarterНадеюсь, это поможет.
весь код, связанный с приложением службы hello world?
К тому же я не могу сказать, что мне нужен Feign. Я доволен restTemplate на данный момент
да, это связано с кодом службы hello world, его следует разместить рядом с HelloWorldStarter
restTemplate не имеет внутри логики аутентификации, с другой стороны, oauth2FeignRequestInterceptor содержит ее.
А что насчет этого docs.spring.io/spring-security/oauth/apidocs/org/…?
Как видите, служба приветствия не защищена. Почему я вижу "Запрещено"?
Вы пробовали использовать
OAuth2RestTemplateвместо обычногоRestTemplate? см. пример здесь stackoverflow.com/questions/27864295/…