SpringSecurity入门体验demo
文章目录
前言
简单体验SpringSecurity框架的功能
建立一个demo,能实现角色登录以及简单的角色分配功能
使用步骤
1.建立一个Spring Boot的简单maven项目,只需要选用Spring Web以及Spring Security的依赖即可
pom文件依赖如下(不需要指定版本,会自动匹配Spring boot的版本进行导入,此处用的是2.5.1版本):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.新建一个自定义的Spring Security配置类
配置类代码如下(主要是重写方法,定义自己的规则):
/**
* Created by Jzs on 2021/6/16
* SpringSecurity配置类
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)//启用了security拦截注解的作用
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
//用户认证管理器
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//注册用户,一个具有管理员权限,一个是普通用户
auth.inMemoryAuthentication()
//指定密码加密器,5.0版本之后如果不进行指定的话会报错
.passwordEncoder(new BCryptPasswordEncoder())
.withUser("admin")
.password(new BCryptPasswordEncoder().encode("123456"))
.roles("ADMIN");
auth.inMemoryAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.withUser("demo")
.password(new BCryptPasswordEncoder().encode("123456"))
.roles("user");
}
//配置资源过滤
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()//将"/"这个请求直接放过不需要验证
.anyRequest().authenticated()
.and()
//将注销请求直接放过不需要验证
.logout().permitAll()
.and()
//支持表单登录
.formLogin();
http.csrf().disable();//关闭csrf保护
}
//配置静态资源过滤
@Override
public void configure(WebSecurity web) throws Exception {
//静态资源过滤
web.ignoring().antMatchers("/js/**","/css/**","/images/**");
}
}
3.新建一个Controller类
Controller类代码如下(主要是提供接口):
@RestController
public class SpringSecurityController {
@GetMapping("/")
public String index(){
return "index";
}
@PreAuthorize("hasRole('ROLE_ADMIN')")//接口请求之前进行判断
@PostAuthorize("returnObject.equals('roleByAdmin')")//接口处理之前进行判断
@GetMapping("/roleByAdmin")
public String roleByAdmin(){
return "roleByAdmin";
}
@PreFilter("filterObject==1")//接口请求之前进行过滤
@PostFilter("filterObject==2")//接口处理之前进行过滤
@GetMapping("/test")
public List<Integer> test(List<Integer> ids){
List<Integer> collect = ids.stream()
.map(m -> m + new Random(2).nextInt())
.collect(Collectors.toList());
return collect;
}
}
可以在代码中看到可以用四种类型的注解,简单的理解为对应对象和集合,都是在请求接口之前和请求接口之后进行处理,可以传递表达式。具体的传参可以根据”SecurityExpressionRoot“这个类进行查看。如果是比较早期的Spring Security的版本可能会出现注解不生效的情况,此时可以在启动类加上@EnableGlobalMethodSecurity(prePostEnabled = true)这个注解。
实现到这里就可以进行简单的用户登录操作以及权限分配。
4.补充
此处只是做了一个简单的demo来体验一下SpringSecurity的功能,并没有关联到数据库,如果需要的话可以根据框架提供的users.ddl或者是自己定义的数据库表结构进行自定义操作。此处需要继承UserDetailsService并对相应的方法进行实现,同时在配置类中进行相对应的操作,同时也可以实现自定义的密码编码器。此处只提供大体上的代码:
/**
* Created by Jzs on 2021/6/16
* 关联上数据库的真实操作地点,具体参数可以点进UserDetails中查看,
* 其中也是继承的user类,可以查看到详细参数
*/
@Component
public class MyUserService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return null;
}
}
/**
* Created by Jzs on 2021/6/16
* 自定义的编码器
* 这个编码器的好处是同一个密码多次加密结果并不一致,但是使用解密的方法可以成功比较
*/
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder.encode(rawPassword);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder.matches(rawPassword,encodedPassword);
}
}
/**
* Created by Jzs on 2021/6/16
* 配置类中的用户认证管理器
*/
@Autowired
MyUserService myUserService;
//用户认证管理器
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());
auth.jdbcAuthentication().usersByUsernameQuery("")
.authoritiesByUsernameQuery("").passwordEncoder(new MyPasswordEncoder());
}