作者:飞天6585_439 | 来源:互联网 | 2023-09-18 08:19
SpringBoot整合Security的博客案例网上已经很多了,但个人觉得对于一个初次整合Security的同学来说,一个简单的案例还是很有必要的。为此,上传一个本人整合的案例,仅供大家参考,也为自己记录一下,话不多说,表演开始。
版本介绍:SpringBoot 2.0.5,JDK 1.8
首先创建SpringBoot项目,能看到这里的同学,相信这一步就不用多说了,可以使用Eclipse中的Spring插件创建,简单又省事。
引入依赖:
4.0.0
com.peng.demo
SpringBoot-security
0.0.1-SNAPSHOT
jar
SpringBoot-security
SpringBoot-security
org.springframework.boot
spring-boot-starter-parent
2.0.5.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
org.springframework.boot
spring-boot-maven-plugin
创建认证类,用于认证用户
public class UserDetailsServiceImpl implements UserDetailsService {
@Reference
private UserService userService;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//构建角色
List authorities=new ArrayList();
authorities.add(new SimpleGrantedAuthority("ADMIN"));
//查询用户
TbUser tbUser = userService.findOne(username);
if (tbUser!=null) {
if (tbUser.getStatus().equals("1")) {
return new User(username,tbUser.getPassword(), authorities);
}else{
return null;
}
}else{
return null;
}
}
}
注:本人在实现本案例的时候,SpringBoot已整合Dubbo,所以其中的UserService是操作用户的service,读者可自己实现,通过查询数据库,返回用户对象。@Reference注解为Dubbo中注解,读者可用@Autowired代替。loadUserByUsername方法中的参数为页面表单中输入的参数值,后台拿到username,通过userService查询数据库,即可判断用户是否存在。返回User对象,即可为用户授权,其中的authorities为用户的角色列表,这个角色列表也可以从数据库中查询出来,具体咋实现,可根据业务进行表设计。
注:SprintBoot2.0.5整合Security时,登录密码需要进行编码,所以在授权时,从数据库中查询的登录密码需要经过编码的,如果不进行编码,需要注入
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
返回的User为,对登陆密码进行编码:
return new User(username,bCryptPasswordEncoder.encode(tbUser.getPassword()), authorities);
创建WebSecurityConfigurerAdapter的实现,配置Security
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//配置用户名及密码及角色
auth.userDetailsService(userDetailsServiceImpl()).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置拦截规则----配置访问所有地址均需要ADMIN权限,使用内存用户使用hasAnyRole验证用户角色,使用数据库用户,使用hasAnyAuthority验证用户权限
http.authorizeRequests().antMatchers("/**").hasAnyAuthority("ADMIN");
//配置登录页面及退出等相关页面
http.formLogin().loginPage("/login.html")//登录页面
.usernameParameter("username").passwordParameter("password")//配置用户名密码参数名称
.loginProcessingUrl("/login")//配置登录请求路径
.defaultSuccessUrl("/admin/index.html",true)//登录成功跳转,并且始终跳转到/admin/index.html
.failureUrl("/login.html")//登录失败跳转
.and().logout().logoutUrl("/logout")//退出登录访问地址
.logoutSuccessUrl("/login.html")//退出成功后访问页面
.and().csrf().disable()//配置不进行csrf拦截
.headers().frameOptions().sameOrigin();//配置可以加载框架页面 如iframe
//自动登录
http.rememberMe()
.tokenValiditySeconds(432000);//设置COOKIE保存时间 单位秒
}
@Override
public void configure(WebSecurity web) throws Exception {
//解决静态资源被拦截的问题
web.ignoring().antMatchers("/*.html","/css/**","/img/**","/js/**");
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsServiceImpl userDetailsServiceImpl() {
return new UserDetailsServiceImpl();
}
}
注:网上看到很多博客写到该配置时都会在当前配置的类头上在加一个@Configuration注解,其实是没必要的,查看@EnableWebSecurity注解源码,即可查看到其实已经配置@Configuration注解啦。在当前配置类中使用@Bean注解向IOC容器中加入密码加密组件及我们自己配置的用户认证组件,重写WebSecurityConfigurerAdapter的三个方法,配置自己的登录及拦截规则,具体解释代码中已有注释。
注:Security也可以配置内存中的用户名及密码,当使用内存用户名及密码时,配置拦截规则可以为:http.authorizeRequests().antMatchers("/**").hasRole("ADMIN");
但使用数据库中的用户名及密码通过GrantedAuthority设置角色时,配置拦截规则为:
http.authorizeRequests().antMatchers("/**").hasAnyAuthority("ADMIN");
这是一个坑,使用错误就会一直提示没有权限
编写登录页面login.html
自动登录
注:登录方式为post提交,提交地址为/login
编写/admin/index.html
登陆成功退出登陆
到此,SpringBoot整合Security就完成了,水平有限,如有错误,希望留言修正。