0

重用用戶的oauth2令牌(authorization_code)我有3個應用程序如何在休息模板

  1. 前端應用
  2. 的OAuth2認證服務器
  3. REST API(RepositoryRestResources)

我用戶必須先登錄才能使用前端應用程序。這是通過SSO發生的。他們收到一個令牌,在客戶進入之前由客戶驗證。

我想重複使用此令牌來發出api請求。我的REST api應用程序使用相同的SSO登錄(它是前端客戶端的資源),但我不知道如何「添加授權標頭」以用於我用於api請求的RestTemplate中。

創建我restTemplate這樣的:

public static RestTemplate build() 
    { 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
     mapper.registerModule(new Jackson2HalModule()); 
     mapper.registerModule(new JavaTimeModule()); 
     MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
     converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); 
     converter.setObjectMapper(mapper); 
     return new RestTemplate(Arrays.asList(converter)); 
    } 

我的資源服務器配置:

@Configuration 
@EnableResourceServer 
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter 
{ 

    @Value("${resource.id}") 
    private String resourceId; 

    @Override 
    public void configure(HttpSecurity http) throws Exception 
    { 
     http 
       .authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS).permitAll() 
       .anyRequest().authenticated() 
       .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); 
    } 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception 
    { 
     resources.resourceId(resourceId); 
    } 


    @Bean 
    public static TokenEnhancer tokenEnhancer() 
    { 
     return new JwtTokenEnhancer(); 
    } 


    @Bean 
    public static JwtAccessTokenConverter accessTokenConverter() 
    { 
     KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "somesecret".toCharArray()); 
     JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 

     converter.setKeyPair(keyStoreKeyFactory.getKeyPair("pair")); 
     return converter; 
    } 

    @Bean 
    public static TokenStore tokenStore() 
    { 
     return new JwtTokenStore(accessTokenConverter()); 
    } 

} 

回答

0

我固定它使用一個截擊手動從安全上下文添加令牌。

public class OAuthInterceptor implements ClientHttpRequestInterceptor 
{ 

    @Autowired 
    private AuthenticationHolder holder; 

    @Override 
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException 
    { 
     if (holder.getToken() == null) 
     { 
      //throw new IOException("Token not set"); 
      System.out.println("##################### Token not set! ###################"); 
     } 
     else 
     { 
      System.out.println("##################### Token found: " + holder.getToken()); 
      HttpHeaders headers = request.getHeaders(); 
      headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + holder.getToken()); 
     } 

     return execution.execute(request, body); 
    } 
} 

我用我在我的客戶端應用程序實現的接口:

public interface AuthenticationHolder 
{ 
    String getToken(); 
} 

@Bean 
public AuthenticationHolder getAuthenticationHolder() 
{ 
    return() -> 
    { 
     Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
     if(authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) 
     { 
      return ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenValue(); 
     } 
     return null; 
    }; 
} 
0

您可以在你的方法頂部使用@PreAuthorize(ROLE),所以,當這方法被調用,他將至於令牌,他將檢查提供的令牌是否具有必要的角色來使用該方法。

當然,您將需要配置您的API以連接到您的OAuth數據庫。

實施例:

@PreAuthorize("ROLE_ADMIN") public void deleteAll(){ ... }

+0

我的API設置正確

RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add(new OAuthInterceptor()); 

在其作爲截擊機的定義。問題是客戶端的休息模板沒有「使用」身份驗證,或者更好地不發送授權頭與其請求。 –