Spring Security(七) 基于表达式/注解的访问控制

一、 基于表达式的访问控制

1 access() 方法使用

之前学习的登录用户权限判断实际上底层实现都是调用access(表达式)

可以通过 access()实现和之前学习的权限控制完成相同的功能。

   1.1 以 hasRole 和 和 permitAll  举例

下面代码和直接使用 permitAll()和 hasRole()是等效的。

2 使用自定义方法

虽然这里面已经包含了很多的表达式(方法)但是在实际项目中很有可能出现需要自己自定义逻辑的情况。

判断登录用户是否具有访问当前 URL 权限。

    2.1 新建接口及实现类

新建接口 com.bjsxt.service.MyService 后新建实现类。

public interface MyService {
	boolean hasPermission(HttpServletRequest request, Authentication authentication);
}
@Component
public class MyServiceImpl implements MyService {
	@Override
	public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
		Object obj = authentication.getPrincipal();
		if(obj f instanceof UserDetails){
			UserDetails user = (UserDetails) obj;
			Collection<? s extends GrantedAuthority> authorities = user.getAuthorities();

			return authorities.contains( new SimpleGrantedAuthority(request.getRequestURI()));
		}
		return  false;
	}
}

2.2 修改配置类

在 access 中通过@bean 的 id 名.方法(参数)的形式进行调用

配置类中修改如下:

// url 拦截 (授权)
http.authorizeRequests()
	.antMatchers("/login.html").access("permitAll")
	.antMatchers("/fail.html").permitAll()
	.anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");

二、 基于注解的访问控制

在 Spring Security 中提供了一些访问控制的注解。这些注解都是默认是都不可用的,需要通过@EnableGlobalMethodSecurity 进行开启后使用。

如果设置的条件允许,程序正常执行。如果不允许会报 500

这些注解可以写到 Service 接口或方法上上也可以写到 Controller或 Controller 的方法上。通常情况下都是写在控制器方法上的,控制接口 URL 是否允许被访问。

1 @Secured

@Secured 是专门用于判断是否具有角色的。能写在方法或类上。

参数要以 ROLE_开头。

  1.1 实现步骤

     1.1.1 开启注解

在 启 动 类 ( 也 可 以 在 配 置 类 等 能 够 扫 描 的 类 上 ) 上 添 加

@EnableGlobalMethodSecurity(securedEnabled = true)

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled =  true)
public s class MyApp {
   public c static d void main(String [] args){
      SpringApplication. run (MyApp. class,args);
   }
}

       1.1.2 在控制器方法上添加@Secured  注解

在 LoginController 中方法上添加注解

@Secured("abc")
@RequestMapping( "/toMain")
public String toMain(){
   return  "redirect:/main.html";
}

       1.1.3 配置类

配置类中方法配置保留最基本的配置即可。

protected d void configure(HttpSecurity http)  throws Exception {
	// 表单认证
	http.formLogin()
		.loginProcessingUrl( "/login") //当发现/login 时认为是登录,需要执行 UserDetailsServiceImpl
		.successForwardUrl( "/toMain") //此处是 post 请求
		.loginPage( "/login.html");


	// url 拦截
	http.authorizeRequests()
		.antMatchers( "/login.html").permitAll() //login.html 不需要被认证
		.anyRequest().authenticated(); //所有的请求都必须被认证。必须登录后才能访问。
	//关闭 csrf 防护
	http.csrf().disable();
}

2 @PreAuthorize/@PostAuthorize

@PreAuthorize 和@PostAuthorize 都是方法或类级别注解。

@PreAuthorize 表示访问方法或类在执行之前先判断权限,大多情况下都是使用这个注解,注解的参数和 access()方法参数取值相同,都是权限表达式。

@PostAuthorize 表示方法或类执行结束后判断权限,此注解很少被使用到。

   2.1 实现步骤

      2.1.1 开启注解

在启动类中开启@PreAuthorize 注解。

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyApp {
	public static void main(String [] args){
		SpringApplication.run (MyApp. class,args);
	}
}

    2.1.2 添加@PreAuthorize

在控制器方法上添加@PreAuthorize,参数可以是任何 access()支持的表达式

@PreAuthorize( "hasRole('abc')")
@RequestMapping( "/toMain")
public String toMain(){
	return  "redirect:/main.html";
}

 

评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页