2016-07-28 137 views
2

我正在使用配置了SSO/OAuth2安全性的Spring Boot應用程序。 身份驗證對我的休息控制器工作正常,現在我需要使用休息端點來保護我的Apache Camel路由。如何使用Spring Security和OAuth2來保護Apache Camel Rest端點的安全

據我瞭解有幾種方法如何做到這一點:

  1. 通過添加auth處理器到我的路線
  2. 通過增加政策(SpringSecurityAuthorizationPolicy)到我的路線
  3. 通過處理選項jetty端點

我試圖通過添加新的認證處理器到我的休息端點,但我堅持這個例外:

org.springframework.security.oauth2.common.exceptions.OAuth2Exception: 沒有的AuthenticationProvider發現 org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken

在調試過程中我看到org.springframework.security.authentication.ProviderManager.getProviders()只包含一個提供者AnonymousAuthenticationProvider所以可能我必須註冊適當的提供者...

有人可以幫我找到正確的方法來解決這個問題嗎?

@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    protected void configure(HttpSecurity http) throws Exception { 
    http.csrf().disable().authorizeRequests().anyRequest().permitAll(); 
    } 

    @Configuration 
    @EnableResourceServer 
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

    @Value("${oauth2.token.endpoint}") 
    private String tokenEndpoint; 

    @Bean 
    public ResourceServerTokenServices tokenService() { 
     RemoteTokenServices tokenServices = new RemoteTokenServices(); 
     tokenServices.setClientId("clientId"); 
     tokenServices.setClientSecret("clientSecret"); 
     tokenServices.setCheckTokenEndpointUrl(tokenEndpoint); 
     return tokenServices; 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().anyRequest().authenticated(); 
    } 
    } 

} 

@Configuration 
public class EmbeddedServerRoute { 
    @Bean 
    public RoutesBuilder embeddedServer() { 
    return new RouteBuilder() { 
     @Override 
     public void configure() throws Exception { 
     restConfiguration().component("jetty").port("8081").bindingMode(RestBindingMode.json); 
     } 
    }; 
    } 
} 


@Component 
public class RestTestRoute extends RouteBuilder { 

    @Autowired 
    private AuthProcessor authProcessor; 

    @Override 
    public void configure() throws Exception { 
    from("rest:get:/test").process(authProcessor).to("mock:end").end(); 
    } 
} 


@Component 
public class AuthProcessor implements Processor { 

    @Autowired 
    private AuthenticationManager authenticationManager; 

    private TokenExtractor tokenExtractor = new BearerTokenExtractor(); 

    private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new OAuth2AuthenticationDetailsSource(); 

    @Override 
    public void process(Exchange exchange) throws Exception { 
    HttpServletRequest request = exchange.getIn().getBody(HttpServletRequest.class); 
    Subject subject = new Subject(); 
    Authentication auth = getAuth(request); 
    subject.getPrincipals().add(auth); 
    exchange.getIn().setHeader(Exchange.AUTHENTICATION, subject); 
    } 

    private Authentication getAuth(HttpServletRequest request) throws OAuth2Exception { 
    Authentication authentication = null; 
    try { 
     authentication = tokenExtractor.extract(request); 
     if (authentication != null) { 
     request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal()); 

     if (authentication instanceof AbstractAuthenticationToken) { 
      AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken) authentication; 
      needsDetails.setDetails(authenticationDetailsSource.buildDetails(request)); 
     } 
     return authenticationManager.authenticate(authentication); 
     } 
    } catch (Exception e) { 
     throw new OAuth2Exception(e.getMessage()); 
    } 
    throw new OAuth2Exception("Not Authorized to view resource"); 
    } 

} 

回答

3

作爲最終解決方案,我決定使用Spring Boot嵌入式servlet容器代替Apache Camel rest組件。所以它可以很容易地被Spring Security保護。這可以通過創建額外的豆來完成:

@Bean 
    public ServletRegistrationBean servletRegistrationBean() { 
    SpringServerServlet serverServlet = new SpringServerServlet(); 
    ServletRegistrationBean regBean = new ServletRegistrationBean(serverServlet, "/camel/*"); 
    Map<String, String> params = new HashMap<>(); 
    params.put("org.restlet.component", "restletComponent"); 
    regBean.setInitParameters(params); 
    return regBean; 
    } 

    @Bean 
    public Component restletComponent() { 
    return new Component(); 
    } 

    @Bean 
    public RestletComponent restletComponentService() { 
    return new RestletComponent(restletComponent()); 
    } 
相關問題