分享一波权限知识 ~ ,Who可以对What进行How的访问操作
轻松扩展并且满足自定义要求
api方便
Security组件
- 引入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
在这个过程中我遇到一个小问题,springboot项目启动的时候,发现启动之后自动停止运行,真的是郁闷了, 最后发现是自己没有在pom文件加入web pom文件,警告一下自己吧~
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 创建 SpringSecurityConfig 继承WebSecurityConfigurerAdapter
重新config方法
表示拦截js和css和images
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**","/css/**","/images/**");
}
对用户进行验证
/**
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//定义的简单规则
http.authorizeRequests()
//路径所有./
.antMatchers("/").permitAll()
//被认证
.anyRequest().authenticated()
.and()
//运行进行表单认证
.logout().permitAll()
.and()
.formLogin();
//关闭csrf的认证
http.csrf().disable();
}
```js
请求检测
@RestController
@EnableAutoConfiguration
public class DemoApplication {
@RequestMapping("/hello")
public String hello(){
return "hello word";
}
}
@RequestMapping("/hello")
public String hello(){
return "hello word";
}
当访问localhost:8080/hello 的时候她会直接让你调到login登陆
通过上面的描述我们知道spring Security api实现了拦截必须登录才可以访问, 假如我们现在根据不同用户有访问接口的不同权限,这个时候如何?
请求的方法上加上@PreAuthorize , 当角色为admin的时候才可以访问api roleAuth ,否则不可以访问
//这句话的意思是启用@PreAuthorize 这个注解,在启动类上面加上
@EnableGlobalMethodSecurity(prePostEnabled = true)
//表示告诉应用与那个权限
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping("/roleAuth")
public String roleAuth(){
return "admin role";
}
需要说明的是我们必须在前缀上加上Role
public class RoleVoter implements AccessDecisionVoter<Object> {
private String rolePrefix = "ROLE_";
有两个角色,一个admin一个user
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin1").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin2").password("123456").roles("USER");
}
如果这个时候我们跟数据库打交道
@Component
public class MyUserService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return null;
}
}
为了安全我们要对密码进行加密,创建类MypasswordEncoder, 实现接口 PasswordEncoder
/**
* 加密方法,表示对原始密码进行加密
* @param charSequence
* @return
*/
@Override
public String encode(CharSequence charSequence) {
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
return md5PasswordEncoder.encodePassword(charSequence.toString(),"123456");
}
/**
* 匹配方法
* @param charSequence
* @param s
* @return
*/
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(charSequence.toString());
}
具体的方法myUserService
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 表示登陆的时候使用那个做个类去做关于数据库方法的权限
auth.userDetailsService(myUserService).passwordEncoder(new MypasswordEncoder());
}
// 方法执行之后做权限认证
@PostAuthorize("hasRole()")
@PreFilter和@PostFilter可以对集合类型的参数或返回值进行过滤, @preFilter表示针对那个参数, @postFilter表示针对当前返回的对象