2016-10-01 77 views
0

在我的春节,启动应用程序,我已经配置了以下ResourceServer:春天的OAuth2安全和ResourceServer配置

@Configuration 
@EnableResourceServer 
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

    @Autowired 
    private ResourceServerTokenServices tokenService; 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) { 
     // @formatter:off 
     resources   
      .resourceId(RESOURCE_ID) 
      .tokenServices(tokenService); 
     // @formatter:on 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http     
      .antMatcher("/api/**") 
      .authorizeRequests().anyRequest().authenticated() 
      .and() 
       .csrf().disable() 
       .sessionManagement().sessionCreationPolicy(STATELESS); 
     // @formatter:on 
    } 

} 

的问题是,我的一些API端点必须不固定,但根据这种配置一切都根据担保/api/**路径。

比如我有一个下面的API端点:

POST /api/v1.0/users/create 

可匿名访问。

如何配置?

此外,是否有可能重写ResourceServerConfiguration.configure法注解中描述的安全规则,例如与@PreAuthorize("permitAll()")

@RestController 
@RequestMapping("/api/v1.0/users") 
public class UsersController { 

    @PreAuthorize("permitAll()") 
    @RequestMapping(value = "/create", method = RequestMethod.POST) 
    public UserResponse create(@RequestBody CreateUserRequest userRequest) { 
     ... 
    } 

} 

可能是我做错了什么但遗憾的是它并没有马上工作。

修订

正如以下建议我增加了新的antMatcherResourceServerConfiguration

@Override 
public void configure(HttpSecurity http) throws Exception { 
    // @formatter:off 
    http     
     .antMatcher("/api/v1.0/users/create").anonymous().and() 
     .antMatcher("/api/**") 
     .authorizeRequests().anyRequest().authenticated() 
     .and() 
      .csrf().disable() 
      .sessionManagement().sessionCreationPolicy(STATELESS); 
    // @formatter:on 
} 

这也是我WebSecurityConfig

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private SocialAuthenticationSuccessHandler socialAuthenticationSuccessHandler; 

    @Autowired 
    private DBUserDetailsService userDetailsService; 

    @Value("${social.postLogin.url}") 
    private String postLoginUrl; 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     // Spring Security ignores request to static resources such as CSS or JS 
     // files. 
     web.ignoring().antMatchers("/static/**"); 
    } 


    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     // @formatter:off 
     http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class); 

     // Set a custom successHandler on the SocialAuthenticationFilter 
     final SpringSocialConfigurer socialConfigurer = new SpringSocialConfigurer(); 
     socialConfigurer.addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() { 
      @Override 
      public <O extends SocialAuthenticationFilter> O postProcess(O socialAuthenticationFilter) { 
       socialAuthenticationFilter.setAuthenticationSuccessHandler(socialAuthenticationSuccessHandler); 
       socialAuthenticationFilter.setPostLoginUrl(postLoginUrl); 
       return socialAuthenticationFilter; 
      } 
     }); 

     http 
      .csrf().ignoringAntMatchers("/api/**") 
      //.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
     .and() 
      .authorizeRequests() 

      .antMatchers("/oauth/authorize").authenticated() 
      //Anyone can access the urls 
      .antMatchers("/api/**").permitAll() 
      .antMatchers("/auth/**").permitAll() 
      .antMatchers("/actuator/health").permitAll() 
      .antMatchers("/actuator/**").hasAuthority("PERMISSION_READ_ACTUATOR_DATA") 
      .antMatchers("/login").permitAll() 
      .anyRequest().authenticated() 
     .and() 
      .formLogin() 
       .loginPage("/login") 
       .loginProcessingUrl("/login") 
       .failureUrl("/login?error=true") 
       .usernameParameter("username") 
       .passwordParameter("password") 
       .permitAll() 
     //Adds the SocialAuthenticationFilter to Spring Security's filter chain. 
     .and() 
      // apply the configuration from the socialConfigurer (adds the SocialAuthenticationFilter) 
      .apply(socialConfigurer); 
     // @formatter:on 
    } 

    /** 
    * Configures the authentication manager bean which processes authentication 
    * requests. 
    */ 
    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 
    } 

    @Override 
    @Bean 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

} 

我仍然收到AccessDeniedException例外:

org.springframework.security.access.AccessDeniedException: Access is denied 
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) 
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) 
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) 
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) 
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Unknown Source) 

回答

1

只需为匿名路径和permin所有角色(包括匿名)添加另一个antMatcher即可。

@Override 
public void configure(HttpSecurity http) throws Exception { 
    // @formatter:off 
    http 
      .antMatcher("/api/**").authorizeRequests() 
      .antMatchers("/api/v1.0/users").permitAll() 
      .anyRequest().authenticated() 
      .and() 
      .csrf().disable() 
      .sessionManagement().sessionCreationPolicy(STATELESS); 
    // @formatter:on 
} 
+0

感谢您的回答,但不幸的是仍然无法正常工作。我更新了我的问题,并提供了更多细节。 – alexanoid

+0

对不起,我太快了:)。我已经更新了答案,这一次我已经在本地尝试过了。 –

+0

谢谢,现在它工作正常。现在,当我需要GET /api/v1.0/users和POST /api/v1.0/users两种不同的访问模型时,我有点担心配置。例如,第一个应该是安全的,第二个公开..如何扩展当前配置以支持这个? – alexanoid