我正在尝试使用受 Oauth2 或 Http-Basic 身份验证保护的资源来实现 API。
当我首先加载将 http-basic 身份验证应用于资源的 WebSecurityConfigurerAdapter 时,不接受 Oauth2 令牌身份验证。反之亦然。
示例配置: 这将 http-basic 身份验证应用于所有 /user/** 资源
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private LoginApi loginApi;
@Autowired
public void setLoginApi(LoginApi loginApi) {
this.loginApi = loginApi;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new PortalUserAuthenticationProvider(loginApi));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/users/**").authenticated()
.and()
.httpBasic();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
这将 oauth 令牌保护应用于 /user/** 资源
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/users/**")
.and()
.authorizeRequests()
.antMatchers("/users/**").access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.hasScope('read')");
}
}
我确定我缺少一些神奇的代码,如果第一个失败,它会告诉 spring 尝试两者?
任何帮助将不胜感激。
原文由 user3613594 发布,翻译遵循 CC BY-SA 4.0 许可协议
我设法根据 Michael Ressler 的回答的提示完成了这项工作,但进行了一些调整。
我的目标是在相同的资源端点上允许 Basic Auth 和 Oauth,例如 /leafcase/123。由于 filterChains 的顺序(可以在 FilterChainProxy.filterChains 中检查),我被困了很长一段时间;默认顺序如下:
由于资源服务器的 filterChains 排名高于由 WebSecurityConfigurerAdapter 配置的 filterchain,并且前者几乎匹配每个资源端点,因此 Oauth 资源服务器逻辑总是启动对资源端点的任何请求(即使请求使用 Authorization:Basic 标头)。你会得到的错误是:
我做了 2 处更改来完成这项工作:
首先,WebSecurityConfigurerAdapter 的排序高于资源服务器(排序 2 高于排序 3)。
其次,让 configure(HttpSecurity) 使用仅匹配“Authorization: Basic”的客户 RequestMatcher。
因此,它会在资源服务器的 filterChain 有机会匹配它之前匹配并处理 Basic Auth 资源请求。它还只处理 Authorizaiton:Basic 资源请求,因此任何带有 Authorization:Bearer 的请求都将失败,然后由资源服务器的 filterChain 处理(即,Oauth 的过滤器启动)。此外,它的排名低于 AuthenticationServer(如果在同一项目上启用了 AuthenticationServer),因此它不会阻止 AuthenticaitonServer 的过滤器链处理对 /oauth/token 等的请求。