SpringSecurity请求授权规则配置与注解详解

 更新时间:2023年12月06日 08:29:42   作者:流烟默  
这篇文章主要介绍了SpringSecurity请求授权规则配置与注解详解,我们常使用@Secured与@PreAuthorize两个注解在进入方法前进行角色、权限的控制,进入方法前数据的过滤@PreFilter注解偶尔会看到,需要的朋友可以参考下

1、请求授权规则配置

这里主要是重写WebSecurityConfigurerAdapter 的configure方法。

protected void configure(HttpSecurity http) throws Exception {
     this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
     ((HttpSecurity)((HttpSecurity)((AuthorizedUrl)http.
	     authorizeRequests()
	     .anyRequest())
	     .authenticated()
	     .and())
	     .formLogin()
	     .and())
	     .httpBasic();
 }

① 自定义登录

这里UsernamePasswordAuthenticationFilter 将起作用。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
            .loginPage("/login.html") //登录页面
            .loginProcessingUrl("/user/login") // 默认处理登录的请求
            .successForwardUrl("/success")  //登录成功后跳转到哪个URL
            .defaultSuccessUrl("/index",true)// 登录成功后跳转路径
            .failureForwardUrl("/fail") //登录失败后跳转到哪个URL
            .permitAll();

}

这里successForwardUrl与defaultSuccessUrl 都可以实现认证成功后跳转的效果,不过具体用法上有所区别。通常建议使用defaultSuccessUrl,至于具体区别后面另开章节学习。

还可以修改用户名和密码的key(默认是username 和password):

.usernameParameter("userName")  //自定义获取用户登录名
.passwordParameter("password")  //自定义获取用户登录密码

② 设置放行与需要认证的请求

 http.authorizeRequests()
               .antMatchers("/static/**","/images/**","/css/**","/js/**")//可以直接放行
               .permitAll()//匹配上述请求的直接放行
               .anyRequest().authenticated();//其他请求都需要认证

③ 基于角色或权限进行访问控制

回顾上文我们自定义实现类设置用户角色权限如下:

在这里插入图片描述

这里用户角色、权限是指定的,那么我们是不是可以升级一下从数据库查询呢?如下图所示:

在这里插入图片描述

hasAuthority 方法

如果当前的主体具有指定的权限,则返回 true,否则返回false。

http.authorizeRequests()
     .antMatchers("/static/**","/images/**","/css/**","/js/**")//可以直接放行
     .permitAll()
     .antMatchers("/findAll").hasAuthority("admin") // 用户访问findAll 必须有 admin 权限
     .anyRequest().authenticated();//其他请求都需要认证

hasAnyAuthority方法

如果当前的主体有任何提供的角色(给定的作为一个逗号分隔的字符串列表)的话,返回true。

http.authorizeRequests()
    .antMatchers("/static/**","/images/**","/css/**","/js/**")//可以直接放行
    .permitAll()
    .antMatchers("/findAll").hasAuthority("admin") // 用户访问findAll 必须有 admin 权限
    .antMatchers("/find").hasAnyAuthority("admin","sale") // 用户访问 find ,拥有admin或者sale之一即可
    .anyRequest().authenticated();//其他请求都需要认证

hasRole 方法

如果用户具备给定角色就允许访问,否则出现403。如果当前主体具有指定的角色,则返回true。

这里需要说明的是在SpringSecurity源码中对hasRole 进行了处理,为角色名自动添加上了ROLE_前缀。故我们配置的时候不加该前缀即可。

org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer#hasRole

在这里插入图片描述

http.authorizeRequests()
     .antMatchers("/static/**","/images/**","/css/**","/js/**")//可以直接放行
     .permitAll()
     .antMatchers("/findAll").hasAuthority("admin") // 用户访问findAll 必须有 admin 权限
     .antMatchers("/find").hasAnyAuthority("admin","sale") // 用户访问 find ,拥有admin或者sale之一即可
     .antMatchers("/sale/**").hasRole("sale") // 需要用户具有sale角色
     .anyRequest().authenticated();//其他请求都需要认证

hasAnyRole方法

表示用户具备任何一个条件都可以访问。

http.authorizeRequests()
     .antMatchers("/static/**","/images/**","/css/**","/js/**")//可以直接放行
     .permitAll()
     .antMatchers("/findAll").hasAuthority("admin") // 用户访问findAll 必须有 admin 权限
     .antMatchers("/find").hasAnyAuthority("admin","sale") // 用户访问 find ,拥有admin或者sale之一即可
     .antMatchers("/sale/**").hasRole("sale") // 需要用户具有sale角色
     .antMatchers("/product/**").hasAnyRole("admin","product") //用户具有admin或者product角色之一即可
     .anyRequest().authenticated();//其他请求都需要认证

④ 自定义403访问拒绝页面

修改配置类

 http.exceptionHandling().accessDeniedPage("/unauth.html");

这里需要说明的是你的静态资源文件路径下比如static下需要有unauth.html页面,当然这里也可以换成一个请求如/unauth,编写controller来处理该请求。

⑤ 自定义退出

修改配置类如下:

http.logout().logoutUrl("/logout")  //退出登录请求
			.logoutSuccessUrl("/index") //注销成功后跳转地址
			.permitAll();

还可以指定在退出时删除某些cookie、注销会话:

.deleteCookies("remember-me","sign")
.invalidateHttpSession(true)

2、SpringSecurity的注解

通过方法上的注解我们可以实现在后端服务上细粒度的权限校验。

主启动类上要添加@EnableGlobalMethodSecurity注解

@SpringBootApplication
@MapperScan("com.jane.mapper")
@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled = true)
public class Securitydemo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Securitydemo1Application.class, args);
    }
}

① @Secured

判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“ 。使用该注解前要先开启注解支持:@EnableGlobalMethodSecurity(securedEnabled=true)

// 测试注解: 
@RequestMapping("testSecured") 
@ResponseBody 
@Secured({"ROLE_normal","ROLE_admin"}) 
public String helloUser() { 
	return "hello,user"; 
}

② @PreAuthorize

先开启注解功能: @EnableGlobalMethodSecurity(prePostEnabled = true)。

@PreAuthorize注解适合进入方法前的权限验证,是一种常见的应用策略。

@RequestMapping("/preAuthorize") 
@ResponseBody 
//@PreAuthorize("hasRole('ROLE_admin')") 
@PreAuthorize("hasAnyAuthority('menu:system')") 
public String preAuthorize(){ 
	System.out.println("preAuthorize"); 
	return "preAuthorize"; 
}

可以看到这里权限表达式中可以使用hasRole、hasAnyRole、hasAuthority 以及hasAnyAuthority来灵活控制。

③ @PostAuthorize

先开启注解功能: @EnableGlobalMethodSecurity(prePostEnabled = true) 。@PostAuthorize 注解很少使用,在方法执行后再进行权限验证,适合验证带有返回值的权限。

@RequestMapping("/testPostAuthorize") 
@ResponseBody 
@PostAuthorize("hasAnyAuthority('menu:system')") 
public String preAuthorize(){ 
	System.out.println("test--PostAuthorize"); 
	return "PostAuthorize"; 
}

④ @PostFilter

@PostFilter :权限验证之后对数据进行过滤。表达式中的 filterObject 引用的是方法返回值List中的某一个元素。通常也很少使用。

如下留下用户名是admin1的数据:

@RequestMapping("getAll") 
@PreAuthorize("hasRole('ROLE_admin')") 
@PostFilter("filterObject.username == 'admin1'") 
@ResponseBody public List<UserInfo> getAllUser(){ 
	ArrayList<UserInfo> list = new ArrayList<>(); 
	list.add(new UserInfo(1l,"admin1","6666")); 
	list.add(new UserInfo(2l,"admin2","888")); 
	return list; 
}

⑤ @PreFilter

@PreFilter: 进入控制器之前对数据进行过滤。

@RequestMapping("getTestPreFilter") 
@PreAuthorize("hasRole('ROLE_admin')") 
@PreFilter(value = "filterObject.id%2==0") 
@ResponseBody public List<UserInfo> getTestPreFilter(@RequestBody List<UserInfo> list){ 
	list.forEach(t-> { System.out.println(t.getId()+"\t"+t.getUsername()); }); 
	return list; 
}

综上,这里我们常使用@Secured与@PreAuthorize两个注解在进入方法前进行角色、权限的控制。

进入方法前数据的过滤@PreFilter注解偶尔会看到,至于方法执行完后进行校验的两个注解@PostAuthorize与@PostFilter几乎不用。

到此这篇关于SpringSecurity请求授权规则配置与注解详解的文章就介绍到这了,更多相关SpringSecurity配置与注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解springboot启动时是如何加载配置文件application.yml文件

    详解springboot启动时是如何加载配置文件application.yml文件

    这篇文章主要介绍了详解springboot启动时是如何加载配置文件application.yml文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • java实现适用于安卓的文件下载线程类

    java实现适用于安卓的文件下载线程类

    本文给大家分享的是java实现适用于安卓的文件下载线程类的代码,有需要的小伙伴可以参考下
    2015-07-07
  • 老生常谈java中的fail-fast机制

    老生常谈java中的fail-fast机制

    下面小编就为大家带来一篇老生常谈java中的fail-fast机制。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Java多线程并发FutureTask使用详解

    Java多线程并发FutureTask使用详解

    Java 的多线程机制本质上能够完成两件事情,异步计算和并发,FutureTask 是基于 Runnable 实现的一个可取消的异步调用 API,本文给大家介绍Java 多线程并发FutureTask及基本使用,需要的朋友可以参考下
    2022-06-06
  • mybatis 实现多条update同时执行

    mybatis 实现多条update同时执行

    这篇文章主要介绍了mybatis 实现多条update同时执行,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • java stream中Collectors的用法实例精讲

    java stream中Collectors的用法实例精讲

    这篇文章主要为大家介绍了java stream中Collectors的用法实例精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 海量数据去重排序bitmap(位图法)在java中实现的两种方法

    海量数据去重排序bitmap(位图法)在java中实现的两种方法

    今天小编就为大家分享一篇关于海量数据去重排序bitmap(位图法)在java中实现的两种方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • String转BigDecimal,BigDecimal常用操作,以及避免踩坑记录

    String转BigDecimal,BigDecimal常用操作,以及避免踩坑记录

    这篇文章主要介绍了String转BigDecimal,BigDecimal常用操作,以及避免踩坑记录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 以武侠形式理解Java LinkedList源码

    以武侠形式理解Java LinkedList源码

    链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址
    2021-11-11
  • 如何获取所有spring管理的bean

    如何获取所有spring管理的bean

    这篇文章主要介绍了如何获取所有spring管理的bean,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论