Spring mvc OAuth2 Spring安全-OAuth2AuthenticationProcessingFilter不工作
嘿,我正在用OAuth2实现Spring应用程序 根据,为了启用具有OAuth2授权的资源请求,我需要添加@EnableResourceServer注释以包含OAuth2AuthenticationProcessingFilter 我添加了这个注释,但不幸的是,启动时并没有在链中调用过滤器 我可以使用curl命令获取访问令牌:Spring mvc OAuth2 Spring安全-OAuth2AuthenticationProcessingFilter不工作,spring-mvc,spring-security,oauth-2.0,spring-security-oauth2,Spring Mvc,Spring Security,Oauth 2.0,Spring Security Oauth2,嘿,我正在用OAuth2实现Spring应用程序 根据,为了启用具有OAuth2授权的资源请求,我需要添加@EnableResourceServer注释以包含OAuth2AuthenticationProcessingFilter 我添加了这个注释,但不幸的是,启动时并没有在链中调用过滤器 我可以使用curl命令获取访问令牌: curl -X POST -H "Authorization: Basic **************************" -v -H &qu
curl -X POST -H "Authorization: Basic **************************" -v -H "Accept: application/json" -d "username=my.user&password=pass&client_id=my.user&client_secret=4e1d635a-7c9d-426b-a942-cc166438f996&grant_type=password&scope=read write" http://localhost:8080/oauth/token
但资源要求:
curl -v -H "Authorization : Bearer ecfa5bfb-c224-4b4a-abf4-cb4a828c2efb" -H "Accept: application/json" http://localhost:8443/oauth/api/meetings/9
给出:
来自服务器的空回复
与主机localhost的连接#0保持不变
下面是我的资源配置:
@Configuration
@EnableWebSecurity
@ComponentScan("com.springapp.mvc")
@EnableResourceServer
@Order(4)
public class Oauth2ResourcesConfigurationAdapter extends ResourceServerConfigurerAdapter {
@Autowired
private OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint;
@Autowired
private PreAuthUserDetailsService preAuthUserDetailsService;
@Autowired
private OAuth2AccessDeniedHandler accessDeniedHandler;
@Autowired
private DefaultTokenServices tokenServices;
@Autowired
private TokenStore tokenStore;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/api/**")
.access("#oauth2.hasScope('read') and #oauth2.hasScope('write') and #oauth2.hasAnyRole('ROLE_USER','ROLE_ADMIN')")
.accessDecisionManager(accessDecisionManager())
.anyRequest()
.fullyAuthenticated();
http
.anonymous()
.disable();
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
http
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
http
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(logoutSuccessHandler())
.invalidateHttpSession(true);
http
.requiresChannel()
.antMatchers("/oauth/api/**")
.requiresSecure();
http
.portMapper()
.http(8080)
.mapsTo(8443);
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.authenticationManager(getAuthenticationManager())
.tokenServices(tokenServices)
.tokenStore(tokenStore);
}
private AuthenticationManager getAuthenticationManager() {
final OAuth2AuthenticationManager oAuth2AuthenticationManager = new OAuth2AuthenticationManager();
oAuth2AuthenticationManager.setTokenServices(tokenServices);
return oAuth2AuthenticationManager;
}
private PreAuthenticatedAuthenticationProvider preAuthAuthenticationProvider() {
final PreAuthenticatedAuthenticationProvider preAuthAuthenticationProvider = new PreAuthenticatedAuthenticationProvider();
preAuthAuthenticationProvider.setPreAuthenticatedUserDetailsService(preAuthUserDetailsService);
return preAuthAuthenticationProvider;
}
private AccessDecisionManager accessDecisionManager() {
return new UnanimousBased(Arrays.<AccessDecisionVoter>asList(new ScopeVoter(),
new AuthenticatedVoter(),
new WebExpressionVoter()));
}
private LogoutSuccessHandler logoutSuccessHandler() {
return new OAuth2SuccessLogoutHandler(tokenStore);
}
static final class OAuth2SuccessLogoutHandler implements LogoutSuccessHandler {
private final TokenStore tokenStore;
public OAuth2SuccessLogoutHandler(final TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
request.toString();
}
}
}
@配置
@启用Web安全性
@组件扫描(“com.springapp.mvc”)
@EnableResourceServer
@订单(4)
公共类OAuth2ResourceConfiguration Adapter扩展了ResourceServerConfigurerAdapter{
@自动连线
专用OAuth2AuthenticationEntryPoint OAuth2AuthenticationEntryPoint;
@自动连线
私有预授权用户详细信息服务预授权用户详细信息服务;
@自动连线
私有OAuth2AccessDeniedHandler accessDeniedHandler;
@自动连线
私人违约代币服务;
@自动连线
私人代币店;
@凌驾
public void configure(HttpSecurity http)引发异常{
http
.授权请求()
.antMatchers(“/oauth/api/**”)
.access(#oauth2.hasScope('read')和#oauth2.hasScope('write')和#oauth2.hasAnyRole('ROLE_USER','ROLE_ADMIN'))
.accessDecisionManager(accessDecisionManager())
.anyRequest()
.fullyaauthenticated();
http
.anonymous()
.disable();
http
.会议管理()
.sessionCreationPolicy(sessionCreationPolicy.NEVER);
http
.例外处理()
.accessDeniedHandler(accessDeniedHandler);
http
.logout()
.logoutUrl(“/oauth/logout”)
.logoutSuccessHandler(logoutSuccessHandler())
.使会话无效(真);
http
.requireChannel()
.antMatchers(“/oauth/api/**”)
.requiresSecure();
http
.portMapper()
.http(8080)
.mapsTo(8443);
}
@凌驾
public void configure(ResourceServerSecurityConfigure资源)引发异常{
资源
.authenticationManager(getAuthenticationManager())
.tokenServices(tokenServices)
.代币店(代币店);
}
私有AuthenticationManager getAuthenticationManager(){
最终OAuth2AuthenticationManager OAuth2AuthenticationManager=新的OAuth2AuthenticationManager();
oAuth2AuthenticationManager.setTokenServices(tokenServices);
返回oAuth2AuthenticationManager;
}
私有预验证身份验证提供程序预验证提供程序(){
final PreAuthenticatedAuthenticationProvider PreauthenticationProvider=新的PreAuthenticatedAuthenticationProvider();
PreAuthenticationProvider.setPreAuthenticationDuserDetailsService(preAuthUserDetailsService);
返回PreAuthenticationProvider;
}
私有访问决策管理器访问决策管理器(){
返回新的UnanimousBased(Arrays.asList(new ScopeVoter(),
新的AuthenticatedVoter(),
新WebExpressionVoter());
}
私有LogoutSuccessHandler LogoutSuccessHandler(){
返回新的OAuth2SuccessLogoutHandler(tokenStore);
}
静态最终类OAuth2SuccessLogoutHandler实现LogoutSuccessHandler{
私人最终代币店代币店;
公共OAuth2SuccessLogoutHandler(最终令牌存储令牌存储){
this.tokenStore=tokenStore;
}
@凌驾
public void onLogoutSuccess(HttpServletRequest请求、HttpServletResponse响应、身份验证)引发IOException、ServletException{
request.toString();
}
}
}
我的问题是:错误在哪里?好的,下面是对Spring初学者的一些建议: 有一个FilterChainProxy类,值得了解它是如何工作的。通常,每个请求都会通过标准过滤器和附加过滤器(在配置中添加)进行过滤 每个WebSecurityConfigureAdapter都必须具有适当的顺序,并且根据此顺序,您的请求将与适当的请求匹配器绑定 请求匹配器提供用于处理请求的筛选器 我的问题是,由于WebAdapter排序不正确,我处理了我的请求,这不是期望的行为。合适的请求匹配器位于进一步的位置 更改了WebAdapters后,修复了所有问题
干杯您需要查看您的authenticationManager Bean。然后在ResourceServer安全配置中检测包含授权标头或access_令牌请求参数的请求 以下是一个工作配置,希望这会有所帮助
@Configuration
@EnableOAuth2Sso
@EnableWebSecurity
protected static class ResourceConfiguration extends WebSecurityConfigurerAdapter {
@Value("${sso.url}")
private String ssoUrl;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
protected TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
@Bean
@Primary
protected ResourceServerTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager authenticationManager = new OAuth2AuthenticationManager();
authenticationManager.setTokenServices(tokenServices());
return authenticationManager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.and().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.GET, "/static/**").permitAll()
.antMatchers(HttpMethod.GET, "/profile/**").permitAll()
.antMatchers(HttpMethod.GET, "/services/**").permitAll()
.anyRequest().authenticated()
.and().logout()
.invalidateHttpSession(true)
.logoutSuccessUrl(ssoUrl+"/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.deleteCookies("JSESSIONID").invalidateHttpSession(true)
.permitAll();
}
}
@Configuration
@EnableResourceServer
@Order(1)
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource-id");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new OAuthRequestedMatcher())
.authorizeRequests().anyRequest().fullyAuthenticated();
}
}
private static class OAuthRequestedMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader("Authorization");
boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
boolean haveAccessToken = request.getParameter("access_token")!=null;
return haveOauth2Token || haveAccessToken;
}
}