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()); 

在其作为截击机的定义。问题是客户端的休息模板没有“使用”身份验证,或者更好地不发送授权头与其请求。 –