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配置与注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 命令行中 javac、java、javap 的使用小结

    命令行中 javac、java、javap 的使用小结

    使用 java 命令运行一个.class文件,需要使用该类的全限定类名,同时需要在当前路径下有该类的包层次文件夹,这篇文章主要介绍了命令行中 javac、java、javap 的使用小结,需要的朋友可以参考下
    2023-07-07
  • 使用Java语言实现一个冒泡排序

    使用Java语言实现一个冒泡排序

    冒泡排序也是一种简单直观的排序算法,基本思想是多次遍历要排序的数组,每次比较相邻的元素,如果顺序不对就交换它们的位置,本篇文章将通过IDE使用 Java 语言实现一个冒泡排序,需要的朋友可以参考下
    2024-03-03
  • Java Springboot之Spring家族的技术体系

    Java Springboot之Spring家族的技术体系

    今天带大家来学习Spring家族的技术体系,文中有非常详细的图文介绍及代码示例,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • Java实现斗地主小游戏

    Java实现斗地主小游戏

    这篇文章主要为大家详细介绍了Java实现斗地主小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Java自定义实现链队列详解

    Java自定义实现链队列详解

    这篇文章主要为大家详细介绍了Java自定义实现链队列的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Kotlin教程之函数和包的定义和流程控制

    Kotlin教程之函数和包的定义和流程控制

    这篇文章主要介绍了Kotlin教程之函数和包的定义和流程控制的相关资料,需要的朋友可以参考下
    2017-05-05
  • 浅析JAVA 循环结构

    浅析JAVA 循环结构

    这篇文章主要介绍了JAVA 循环结构的相关资料,文中讲解的非常细致,示例代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • Java中避免空指针的几种方法解析

    Java中避免空指针的几种方法解析

    这篇文章主要介绍了Java中避免空指针的几种方法解析,Java 中任何对象都有可能为空,当我们调用空对象的方法时就会抛出 NullPointerException 空指针异常,这是一种非常常见的错误类型,需要的朋友可以参考下
    2023-12-12
  • Spring使用AspectJ的注解式实现AOP面向切面编程

    Spring使用AspectJ的注解式实现AOP面向切面编程

    这篇文章主要介绍了Spring使用AspectJ的注解式实现AOP面向切面编程的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • java JOptionPane类的介绍

    java JOptionPane类的介绍

    java JOptionPane类的介绍,需要的朋友可以参考一下
    2013-04-04

最新评论