首先,先创建springboot项目(这里我的版本号采用的是spring boot2.0),选择引入web和security的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
现在,我们创建一个Controller
类作为接口进行测试:
@RestController
public class DemoController{
@GetMapping("/")
public String home(){
return "hello hdonghong~";
}
}
启动Spring Boot项目后,进行访问,当页面自动跳转到/login
下面时说明security的环境已经搭建成功:
接下来,我们正式进行Spring Security的配置。
在刚刚创建的Controller类中增加一个接口test:
@GetMapping("/test")
public String test(){
return "test authentication";
}
然后创建SpringSecurityConfig
类并继承WebSecurityConfigurerAdapter
类,具体实现如下:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
//允许访问项目主路径/的请求
//其它请求都要经过拦截验证
//同时也允许注销请求
//支持表单验证登录
//取消掉默认的csrf认证
http.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.logout().permitAll()
.and()
.formLogin();
http.csrf().disable();
}
}
现在启动项目,继续访问http://localhost:8080/会发现可以成功访问了,而访问http://localhost:8080/test则会被拦截。因为我们在SpringSecurityConfig
类中配置了放行主路径/
的请求和注销
请求,而拦截所有其他请求。【这里省略演示过程】
好了,我们继续完善配置。Controller类中新增一个接口test2:
//ROLE_是SpringS ecurity要求的权限前缀,参考源码:private String defaultRolePrefix = "ROLE_";
//这里@PreAuthorize注解发生在方法执行前,意思是要求执行此方法要有ADMIN权限
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/test2")
public String test2(){
return "admin auth";
}
回到SpringSecurityConfig
类中,新增重写父类的configure
方法:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//注意:使用springsecurity5,需要加上{noop}指定使用NoOpPasswordEncoder给DelegatingPasswordEncoder去校验密码
//,同时需要知道NoOpPasswordEncoder已经过时了,这里仅是为了方便
auth.inMemoryAuthentication().withUser("admin").password("{noop}admin").roles("ADMIN");
auth.inMemoryAuthentication().withUser("scott").password("{noop}scott").roles("USER");
}
重新启动项目,现在访问http://localhost:8080/test输入账号/密码为admin/admin就可以通过验证,而其它的如scott用户则不可以。
【这里省略演示过程】
到这里,我们的Spring Security配置还没有结束,我们继续进行最后一步。
创建一个MyPasswordEncoder
并实现PasswordEncoder
接口,具体实现如下:
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence){
BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
return bCryptEncoder.encode(charSequence);
}
@Override
public boolean matches(CharSequence charSequence,String s) {
BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
return bCryptEncoder.matches(charSequence, s);
}
}
这个是密码校验类,我们这里采用了bCrypt加密算法(PS:原本打算用MD5的,可是发现似乎Spring Security5没有了这个MD5的Encode类,在StackOverflow搜索,由于个人搜索能力有限,也没弄明白,恳请知道的大佬解答下)。
现在,我们回到SpringSecurityConfig
类中修改configure
方法的实现:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//使用自己的密码校验类
auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());
//数据库管理方面支持的默认处理
auth.jdbcAuthentication()
.usersByUsernameQuery("")
.authoritiesByUsernameQuery("")
.passwordEncoder(new MyPasswordEncoder());
}
至此,Spring Security环境搭建完毕,当然一些注解如@PreAuthrize、@PostAuthrize、@PreFilter、@PostFilter等注解的使用方式比较复杂,无关本篇文章的主题,所以我就没有叙述,不过其简单使用已经注释在源代码中了。-> 获取源码