首页 > 编程语言 > Spring Security permitAll()不允许匿名访问的操作
2021
09-14

Spring Security permitAll()不允许匿名访问的操作

Spring Security permitAll()不允许匿名访问

修改前

 http
        .addFilterBefore(muiltpartFilter, ChannelProcessingFilter.class)
        .addFilterBefore(cf, ChannelProcessingFilter.class)
        .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
        .authorizeRequests()
            .antMatchers("/ping**")
            .permitAll()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
        .logoutSuccessUrl("/login");

修改后

 http
        .addFilterBefore(muiltpartFilter, ChannelProcessingFilter.class)
        .addFilterBefore(cf, ChannelProcessingFilter.class)
        .authorizeRequests()
            .antMatchers("/ping**")
            .permitAll()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
        .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
        .logout()
            .logoutUrl("/logout")
        .logoutSuccessUrl("/login");

permitAll() 顺序很重要,如同在 XML 配置中,即把 authorizeRequests().anyRequest().authenticate 放到最后

Spring Security @PreAuthorize 拦截无效

1. 在使用spring security的时候使用注解

@PreAuthorize("hasAnyRole('ROLE_Admin')")

放在对方法的访问权限进行控制失效,其中配置如:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Autowired
    UserDetailsService userDetailsService;
 
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/res/**", "/login/login*").permitAll()
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/login/login").defaultSuccessUrl("/")
                .passwordParameter("password")
                .usernameParameter("username")
            .and().logout().logoutSuccessUrl("/login/login");
    }
}

Controller中的方法如下:

@Controller
@RequestMapping("/demo")
public class DemoController extends CommonController{
    @Autowired
    private UserService userService;
 
    @PreAuthorize("hasAnyRole('ROLE_Admin')")
    @RequestMapping(value = "user-list")
    public void userList() {
         
    }
}

使用一个没有ROLE_Admin权限的用户去访问此方法发现无效。

修改一下 SecurityConfig:

  @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.csrf().disable()
           .authorizeRequests()
           .antMatchers("/res/**", "/login/login*").permitAll()
           .antMatchers("/demo/user-list").access("hasRole('ROLE_Admin')")
           .anyRequest().authenticated()
           .and().formLogin().loginPage("/login/login").defaultSuccessUrl("/")
               .passwordParameter("password")
               .usernameParameter("username")
           .and().logout().logoutSuccessUrl("/login/login");
   }

添加上:

.antMatchers("/demo/user-list").access("hasRole('ROLE_Admin')")

可以被正常拦截,说明是方法拦截没有生效。

如果是基于xml,则需要在配置文件中加上:

<security:global-method-security pre-post-annotations="enabled" proxy-target-class="true" />

换成Annotation方式以后,则需要使用 @EnableGlobalMethodSecurity(prePostEnabled=true) 注解来开启。

并且需要提供以下方法:

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

才可正常拦截。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持自学编程网。

编程技巧