我正在使用配置了 SSO/OAuth2 安全性的 Spring Boot 应用程序。
身份验证适用于我的休息 Controller ,现在我需要使用休息端点保护我的 Apache Camel 路由。
据我了解,有几种方法可以做到:
我试图通过向我的休息端点添加新的身份验证处理器来做到这一点,但我坚持这个异常(exception):
org.springframework.security.oauth2.common.exceptions.OAuth2Exception: No AuthenticationProvider found for org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
在调试期间我看到 org.springframework.security.authentication.ProviderManager.getProviders() 仅包含一个提供程序 匿名身份验证提供者 所以可能我必须注册适当的提供者...
有人可以帮我找到解决这个问题的正确方法吗?
@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");
}
}
最佳答案
作为最终解决方案,我决定使用 Spring Boot 嵌入式 servlet 容器而不是 Apache Camel rest 组件。所以它可以很容易地被 Spring Security 保护。这可以通过创建额外的 bean 来完成:
@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());
}
关于spring-security - 如何使用 Spring Security 和 OAuth2 保护 Apache Camel rest 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38638480/