SpringSecurity配置类--常用配置

SpringSecurity配置类

在学习这门课的时候,实现各种功能时进行了各种配置。我想将各种配置综合讲述一下。

首先自定义配置类,需要继承WebSecurityConfigurerAdapter这个类。

在这个类里面做了一些默认配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
	....
}

自定义密码的加密方式:

更改PasswordEncoder的实现为BCryptPasswordEncoder

/**
 *  配置用户密码加密方式
 */
@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder(); // 这里使用 BCrypt (也可换别的)
}

注入Security工作图中的第二步–>用于验证JWT

​ 在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要在SecurityConfig中配置把AuthenticationManager注入容器。

注入AuthenticationManager,用它的方法进行认证

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

使用时:

authenticationManager.authenticate()

安全过滤器链配置方法HttpSecurity http配置方法

默认配置

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
}

super.configure(http);使用了父类中一些默认配置。查看源代码

protected void configure(HttpSecurity http) throws Exception {
    ((HttpSecurity)((HttpSecurity)((AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated()
                     .and())
     				.formLogin()
     				.and())
    				.httpBasic();
}

http.authorizeRequests().anyRequest().authenticated()表示对任何请求都要进行权限认证

http.formLogin(),加入了UsernamePasswordAuthenticationFilter过滤器。

默认配置:

  • 所有的请求访问都需要被授权。
  • 使用 form 表单进行登陆(默认路径为/login),也就是前几篇我们见到的登录页。
  • 防止 CSRF 攻击、XSS攻击。
  • 启用 HTTP Basic 认证

自定义配置

  • 关闭防止csrf攻击

    //前后端分离的项目需要关闭csrf
    http.csrf().disable()
    

    为什么要关闭防止csrf攻击?

    CSRF是指跨站请求伪造(Cross-site request forgery),是web常见的攻击之一。

    https://blog.csdn.net/freeking101/article/details/86537087

    SpringSecurity去防止CSRF攻击的方式就是通过csrf_token。后端会生成一个csrf_token,前端发起请求的时候需要携带这个csrf_token,后端会有过滤器进行校验,如果没有携带或者是伪造的就不允许访问。

    但是在前后端分离的项目中我们的认证信息其实是token,而token并不是存储中cookie中,并且需要前端代码去把token设置到请求头中才可以,所以CSRF攻击也就不用担心了。

    因此使用token是天然防止csrf攻击的。

  • 不通过Session获取SecurityContext

    //不通过Session获取SecurityContext
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    

1. 权限配置

参考链接:

https://blog.csdn.net/qq_41865652/article/details/123685248

https://blog.csdn.net/Shair911/article/details/104181917/

http.authorizeRequests()主要是对url进行访问权限控制,通过这个方法来实现url授权操作。

http.authorizeRequests()也支持连缀写法,总体公式为:

​ url 匹配规则. 权限控制方法

1. anyRequest()
  • anyRequest(),表示匹配所有的url请求

    http.authorizeRequests()
            // 匹配所有的请求,并且所有请求都需要登录认证
            .anyRequest().authenticated();
    

2. antMatcher()
  • antMatcher(String regx),传递一个ant表达式参数,表示匹配所有满足ant表达式的请求

    • ant表达式中特殊字符解释

      规则解释说明
      匹配一个字符
      *匹配0个或多个字符
      **匹配0个或多个目录

      配置类代码示例:

      http.authorizeRequests()
              // 允许登录页面匿名访问
              .antMatchers("/showLogin", "/errPage").anonymous()
              // 所有的静态资源允许匿名访问
              .antMatchers(
                      "/css/**",
                      "/js/**",
                      "/images/**",
                      "/fonts/**",
                      "/favicon.ico"
                      ).anonymous()
              // 其他所有的请求都需要登录认证
              .anyRequest().authenticated();
      
  • antMatcher(HttpMethod.*, String regx),传递一个请求方法类型参数加ant表达式参数,表示匹配所有满足ant表达式的指定请求方式的url

    请求方式的枚举类如下:

    配置类代码示例:

    http.authorizeRequests()
        // 允许GET请求登录页面匿名访问
        .antMatchers(HttpMethod.GET, "/showLogin", "/errPage").anonymous();
    

3. regexMatchers()
  • regexMatchers()使用正则表达式进行匹配。和 antMatchers()主要的区别就是参数,

    antMatchers()参数是 ant 表达式,regexMatchers()参数是正则表达式。

    演示所有以.js 结尾的文件都被放行。

    http.authorizeRequests()
        // 所有以.js 结尾的文件都被放行
    	.regexMatchers( ".+[.]js").permitAll()
    
  • 两个参数时使用方式

    无论是 antMatchers()还是 regexMatchers()都具有两个参数的方法,其中第一个参数都是 HttpMethod,表示请求方式,当设置了HttpMethod 后表示只有设定的特定的请求方式才执行对应的权限设置。

    • 枚举类型 HttpMethod 内置属性如下:
      -在这里插入图片描述

4. mvcMatchers()
  • mvcMatchers()适用于配置了 servletPath 的情况。

    ​ servletPath 就是所有的 URL 的统一前缀。在 SpringBoot 整合SpringMVC 的项目中可以在 application.properties 中添加下面内容设置 ServletPath

    spring.mvc.servlet.path=/bjsxt
    

    ​ 在 Spring Security 的配置类中配置.servletPath()是 mvcMatchers()返回值特有的方法,antMatchers()和 regexMatchers()没有这个方法。在 servletPath()中配置了 servletPath 后,mvcMatchers()直接写 SpringMVC 中@RequestMapping()中设置的路径即可。

    http.authorizeRequests()
    	.mvcMatchers("demo").servletPath("/bjsxt").permitAll()
    

    ​ 如果不习惯使用 mvcMatchers()也可以使用 antMatchers(),下面代码和上面代码是等效的

    http.authorizeRequests()
    	.antMatchers( "/bjsxt/demo").permitAll()
    

2. 访问控制方法

方法名称方法作用
permitAll()表示所匹配的URL任何人都允许访问
anonymous()表示可以匿名访问匹配的URL。和permitAll()效果类似,只是设置为anonymous()的url会执行filterChain中的filter
denyAll()表示所匹配的URL都不允许被访问。
authenticated()表示所匹配的URL都需要被认证才能访问
rememberMe()允许通过remember-me登录的用户访问
access()SpringEl表达式结果为true时可以访问
fullyAuthenticated()用户完全认证可以访问(非remember-me下自动登录)
hasRole()如果有参数,参数表示角色,则其角色可以访问
hasAnyRole()如果有参数,参数表示角色,则其中任何一个角色可以访问
hasAuthority()如果有参数,参数表示权限,则其权限可以访问
hasAnyAuthority()如果有参数,参数表示权限,则其中任何一个权限可以访问
hasIpAddress()如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问

配置案例示例:

//任何用户都可以访问
http.authorizeRequests().antMatchers("/index").permitAll();
http.authorizeRequests().antMatchers("/index").access("permitAll");]

//任何用户都不能访问
http.authorizeRequests().antMatchers("/home").denyAll();
http.authorizeRequests().antMatchers("/home").access("denyAll");

//认证用户可以访问(除了匿名认证)
http.authorizeRequests().antMatchers("/admin").authenticated();
http.authorizeRequests().antMatchers("/admin").access("authenticated");

//认证用户可以访问(除了匿名认证,记住我)
http.authorizeRequests().antMatchers("/admin").fullyAuthenticated();
http.authorizeRequests().antMatchers("/admin").access("fullyAuthenticated");
		
//记住我的认证可以访问
http.authorizeRequests().antMatchers("/admin").rememberMe();
http.authorizeRequests().antMatchers("/admin").access("rememberMe");

//匿名用户可以访问
http.authorizeRequests().antMatchers("/admin").anonymous();
http.authorizeRequests().antMatchers("/admin").access("anonymous");

//是否有权限
http.authorizeRequests().antMatchers("/index").hasAuthority("user");
http.authorizeRequests().antMatchers("/index").access("hasAuthority('user')");

//是否有任意一个权限
http.authorizeRequests().antMatchers("/home").hasAnyAuthority("update", "delete", "insert");
http.authorizeRequests().antMatchers("/home").access("hasAnyAuthority('update','delete','insert')");

//spring security中的role并非是一个或多个权限的集合,而是权限的一种,通常以ROLE_开头
//role就是ROLE_开头的权限
//注意:hasRole、hasAnyRole里面的role不需要以ROLE_开头,否则会报异常
//注意:如果在access里面使用hasRole、hasAnyRole则ROLE_前缀可加,可不加
http.authorizeRequests().antMatchers("/index").hasRole("GUEST");
http.authorizeRequests().antMatchers("/index").access("hasRole('GUEST')");
http.authorizeRequests().antMatchers("/admin").hasAuthority("ROLE_GUEST");
http.authorizeRequests().antMatchers("/home").hasAnyRole("GUEST", "USER", "ADMIN");
http.authorizeRequests().antMatchers("/home").access("hasAnyRole('ROLE_GUEST','ROLE_USER','ROLE_ADMIN')");

添加过滤器到过滤器链

  • 先将获取过滤器

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; // 注入Jwt认证过滤器
    
  • 然后配置到过滤器链中

    http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    //将jwtAuthenticationTokenFilter 过滤器放到UsernamePasswordAuthenticationFilter过滤器前。
    
    • addFilterBefore():将过滤器放到 **过滤器之前。

    • addFilter():将过滤器放到过滤器链最后。

    • addFilterAfter():将过滤器放到 **过滤器之后。

      http.addFilterAfter(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
      //将jwtAuthenticationTokenFilter 过滤器放到UsernamePasswordAuthenticationFilter过滤器后。
      
    • addFilterAt:将过滤器放在**过滤的位置。并不是取代。

配置异常处理器

  • 先获取异常处理器

    @Autowired
    AuthenticationEntryPoint authenticationEntryPoint;  // 注入(自定义的 认证过程中 出现异常的处理方法)
    
    @Autowired
    AccessDeniedHandler accessDeniedHandler;  // 注入(自定义 授权过程中 出现异常的处理方法)
    
  • 然后进行配置。

    /**
     * 配置异常处理器
     */
    http.exceptionHandling()
            .authenticationEntryPoint(authenticationEntryPoint)  // 配置认证失败处理器
            .accessDeniedHandler(accessDeniedHandler);           // 配置授权失败处理器
    

表单登录配置

取消默认的自带的表单登录配置

http.formLogin().disable();

配置演示

@SpringBootConfiguration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	protected void configure(HttpSecurity http) throws Exception  {
		http
			.formLogin()//开启formLogin默认配置			        
				.loginPage("/login/auth").permitAll()//请求时未登录跳转接口
		                .failureUrl("/login/fail")//用户密码错误跳转接口
				.defaultSuccessUrl("/login/success",true)//登录成功跳转接口
				.loginProcessingUrl("/login")//post登录接口,登录验证由系统实现
				.usernameParameter("username")	//要认证的用户参数名,默认username
				.passwordParameter("password")	//要认证的密码参数名,默认password
				.and()
			.logout()//配置注销
				.logoutUrl("/logout")//注销接口
				.logoutSuccessUrl("/login/logout").permitAll()//注销成功跳转接口
				.deleteCookies("myCookie") //删除自定义的cookie
				.and()
			.csrf().disable();           //禁用csrf
	}
}

使用formLogin()就会添加如下过滤器

  • UsernamePasswordAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter

添加认证成功处理器和认证失败处理器

先获取认证成功处理器和认证失败处理器。

@Autowired
private AuthenticationSuccessHandler successHandler;

@Autowired
private AuthenticationFailureHandler failureHandler;

然后再进行配置

 http.formLogin()
    	//配置认证成功处理器
      .successHandler(successHandler)
		//配置认证失败处理器
      .failureHandler(failureHandler);

总的配置代码


@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启SecurityConfig 权限控制功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; 

    @Autowired
    AuthenticationEntryPoint authenticationEntryPoint; 

    @Autowired
    AccessDeniedHandler accessDeniedHandler;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //前后端分离的项目需要关闭csrf
                .csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 对于登录接口 允许匿名访问
                .antMatchers("/user/login").anonymous()
                // 除上面外的所有请求全部都需要认证即可访问
                .anyRequest().authenticated();

        
        http.exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)  // 配置认证失败处理器
                .accessDeniedHandler(accessDeniedHandler);           // 配置授权失败处理器

        //关闭默认的注销功能
        http.logout().disable();

        //把token校验过滤器添加到过滤器链中
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        // 允许跨域
        http.cors();


    }


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


    /**
     *  配置用户密码加密方式
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(); // 这里使用 BCrypt (也可换别的)
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值