我一直在尝试使用Dave Syer的指南实现OAuth2身份验证服务器,并获得了JHipster的一些灵感。但我无法弄清楚这一切是如何协同工作的。
使用ResourceServerConfigurerAdapter时,看起来使用WebSecurityConfigurerAdapter的安全设置会被覆盖。
@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {
private TokenExtractor tokenExtractor = new BearerTokenExtractor();
@Override
public void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(contextClearer(), AbstractPreAuthenticatedProcessingFilter.class)
.authorizeRequests()
.anyRequest().authenticated().and().httpBasic();
}
private OncePerRequestFilter contextClearer() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (tokenExtractor.extract(request) == null) {
SecurityContextHolder.clearContext();
}
filterChain.doFilter(request, response);
}
};
}
@Component
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private final AuthenticationManager authenticationManager;
@Autowired
public CustomWebSecurityConfigurerAdapter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.parentAuthenticationManager(authenticationManager);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login").permitAll()
.and()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.and()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests().anyRequest().authenticated();
}
}
这是从几个不同的例子中获取的代码,因此它们可能不会很好地混合。但是我无法为OAuth2找到一个好的文档/示例列表(与Spring Boot不同,它有一个很棒的文档),所以我在理解所有这些文档是如何组合在一起时遇到了问题。 如果我没有将loginForm添加到ResourceServerConfigurerAdapter,它只会给我未经授权。但我在WebSecurityConfigurererAdapter中将其定义为permitAll()。
这是AuthorizationServerConfigurerAdapter:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("acme")
.secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token",
"password").scopes("openid");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
}
我做错了什么?我是否必须在ResourceServerConfigurerAdapter中设置所有安全性?我是否还需要WebSecurityConfigurerAdapter?
如果有人知道任何指南,教程,博客或类似内容可能有助于我了解其工作方式,那将非常感激。
亲切的问候,肯尼思。
答案 0 :(得分:39)
您需要WebSecurityConfigurerAdapter
来保护/授权端点并为用户提供进行身份验证的方法。 Spring Boot应用程序会为您执行此操作(通过添加自己的WebSecurityConfigurerAdapter
和HTTP基本身份验证)。默认情况下,它会创建一个order = 0的过滤器链,并保护所有资源,除非您提供请求匹配器。 @EnableResourceServer
做了类似的事情,但它添加的过滤器链默认为order = 3。 WebSecurityConfigurerAdapter
有一个@Order(100)注释。因此,首先检查ResourceServer(身份验证),然后检查您在WebSecurityConfigureAdapter的扩展中的检查。
您的配置看起来很清晰(登录链优先,但只匹配一小组请求)。