5

Tôi đang làm việc trên một ít bằng chứng về khái niệm cho một tập hợp các điểm cuối cần có khả năng gọi cho mỗi mã thông báo khác được lấy thông qua luồng thông tin khách OAuth 2 . Tôi đang sử dụng Spring Boot và các dự án có liên quan để xây dựng các thiết bị đầu cuối, và tôi bối rối là tại sao khuôn khổ dường như là rất khăng khăng về đoạn mã sau:Có cách nào dễ dàng hơn để tải cấu hình máy khách Spring OAuth

package com.example.client; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.oauth2.client.OAuth2ClientContext; 
import org.springframework.security.oauth2.client.OAuth2RestOperations; 
import org.springframework.security.oauth2.client.OAuth2RestTemplate; 
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; 
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; 
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

@Configuration 
@EnableAutoConfiguration 
@EnableOAuth2Client 
@RestController 
public class StuffClient { 

    @Value("${security.oauth2.client.access-token-uri}") 
    private String tokenUrl; 

    @Value("${security.oauth2.client.id}") 
    private String clientId; 

    @Value("${security.oauth2.client.client-secret}") 
    private String clientSecret; 

    @Value("${security.oauth2.client.grant-type}") 
    private String grantType; 

    @Autowired 
    private OAuth2RestOperations restTemplate; 

    private String uri = "http://localhost:8082/stuff/"; 

    @RequestMapping(value = "/client/{stuffName}", method = RequestMethod.GET) 
    public String client(@PathVariable("stuffName") String stuffName) { 
     String request = uri + stuffName; 
     return restTemplate.getForObject(request, String.class); 
    } 

    @Bean 
    public OAuth2RestOperations restTemplate(OAuth2ClientContext clientContext) { 
     return new OAuth2RestTemplate(resource(), clientContext); 
    } 

    @Bean 
    protected OAuth2ProtectedResourceDetails resource() { 
     ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails(); 
     resource.setAccessTokenUri(tokenUrl); 
     resource.setClientId(clientId); 
     resource.setClientSecret(clientSecret); 
     resource.setGrantType(grantType); 
     return resource; 
    } 
} 

Và các tập tin cấu hình đi kèm:

server: 
    port: 8081 

security: 
    basic: 
    enabled: false 
    oauth2: 
    client: 
     id: test-client 
     client-secret: test-secret 
     access-token-uri: http://localhost:8080/uaa/oauth/token 
     grant-type: client_credentials 

Các công trình trên chính xác như mong đợi. Nếu tôi thay đổi security.oauth2.client.id để security.oauth2.client.client-id (trong cả hai mã Java và YAML), tôi nhận được một lỗi 500, dòng đầu tiên trong số đó là:

org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException: Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it. 

Mã này cũng hoạt động tốt nếu tôi giá trị mã cứng cho tất cả các các biến mẫu. Dường như nó hoạt động tốt, trên thực tế, trong mỗi hoán vị của các biến thể hiện như vậy, ngoại trừ trường hợp tôi sử dụng @Value để điền clientId với giá trị security.oauth2.client.client-id

Vì vậy, câu hỏi chính của tôi là: cách cụ thể? Và nếu có, tại sao? Và, tôi có thể tận dụng ý kiến ​​này để đơn giản hóa mã của tôi không?

Trả lời

0

Tôi không chắc bạn đang sử dụng phiên bản khởi động mùa xuân nào. Tôi đang sử dụng phiên bản mùa xuân-boot 1.5.4.RELEASED và để đơn giản hóa mã của bạn,

bạn có thể tiêm OAuth2ProtectedResourceDetails như

@Autowired 
private OAuth2ProtectedResourceDetails resource; 

và tạo OAuth2RestTemplate như

@Bean 
@Primary 
public OAuth2RestOperations restTemplate(OAuth2ClientContext clientContext) { 
    return new OAuth2RestTemplate(resource, clientContext); 
} 

mẫu yaml ..

### OAuth2 settings ### 
security: 
    user: 
    password: none 
    oauth2: 
    client: 
     accessTokenUri: ${auth-server}/oauth/token 
     userAuthorizationUri: ${auth-server}/oauth/authorize 
     clientId: myclient 
     clientSecret: secret 
    resource: 
     user-info-uri: ${auth-server}/sso/user 
     jwt: 
     keyValue: | 
      -----BEGIN PUBLIC KEY----- 
      your public key 
      -----END PUBLIC KEY----- 

Và sau đó, sử dụng ví dụ restTemplate trong bộ điều khiển dưới dạng

@Autowired 
private OAuth2RestOperations restTemplate; 

Tôi hy vọng một số sẽ giúp ích cho bạn.

Các vấn đề liên quan