本章只是一个小入门 SpringSecurity的功能是否强大,用户、角色、权限,还有注解配置控制器可以参考下一章,或者官方文档。
目录
1、创建工程
或者
<!--security安全-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!--thymeleaf模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、简介
Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!
记住几个类:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
3、WebSecurityConfigurerAdapter
3.1 创建配置类
@EnableWebSecurity//开启Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
}
//认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
}
3.2、授权规则
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRoles("vip2","vip3")
.antMatchers("/level3/**").hasRole("vip3");
测试发现在没有登录的情况下只能进入首页,其他页面必须登录并且有相对应的角色才能访问
3.3、开启登录、注销、记住我
//没有权限默认跳转到登录页,需要开启登录到页面
http.formLogin();
//关闭csrf功能
http.csrf().disable();
//注销,开启注销功能,跳转首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe();
点击记住我登录功能可以发现多了一条cookir用来记录到期时间
3.4、添加自定义登录页面
<input type="checkbox" name="remember"> 记住我
//自定义表单的name属性同名
http.rememberMe().rememberMeParameter("remember");
//自定义login页 默认登录请求页和登录页是应该页面 当然你可以如果loginProcessingUrl自定义
http.formLogin().loginPage("/toLogin")
//以下三个参数可以选择性使用
.loginProcessingUrl("login")//自定义登录请求
//自定义用户账号表单名 如果前端账号密码表单不是username 和password
.usernameParameter("reusername")
.passwordParameter("repassword");
4、AuthenticationManagerBuilder
4.1、添加认证规则
- 使用内存
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
在内存中定义,也可以在jdbc中去拿....
//Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
//要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
//spring security 官方推荐的是使用bcrypt加密方式。
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("leitoqing").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
- 使用jdbc
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password, enabled from users where username = ?")
.authoritiesByUsernameQuery("select username, role from user_roles where username = ?");
}
5、前端
5.1、导入命名空间
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
5.2、修改导航栏,增加认证判断
- sec:authorize 是否显示
- isAuthenticated() 判断是否登录
<!--登录注销-->
<div class="right menu">
<!--如果未登录-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/login}">
<i class="address card icon"></i> 登录
</a>
</div>
<!--如果已登录-->
<div sec:authorize="isAuthenticated()">
<a class="item">
<i class="address card icon"></i>
用户名:<span sec:authentication="principal.username"></span>
角色:<span sec:authentication="principal.authorities"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="address card icon"></i> 注销
</a>
</div>
</div>
5.3、角色判断
<!-- sec:authorize="hasRole('vip1')" -->
<div class="column" sec:authorize="hasRole('vip1')">
...
</div>
<div class="column" sec:authorize="hasRole('vip2')">
...
</div>
<div class="column" sec:authorize="hasRole('vip3')">
...
</div>
5.4、登录看看
发现2显示不了因为没有这个角色
7、完整性代码
@EnableWebSecurity//开启Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人都可以访问,功能页只有对应有权限都人才能访问
http.authorizeRequests()
.antMatchers("/").permitAll()//首页放行
.antMatchers("/level1/**").hasAnyRole("vip1", "vip2")///level1/开头需要什么角色
.antMatchers("/level2/**").hasRole("vip2");
//没有权限默认跳转到登录页,需要开启登录到页面
http.formLogin();
//关闭csrf功能
http.csrf().disable();
//注销,开启注销功能,跳转首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe();
// 自定义login页 默认登录请求页和登录页是应该页面 当然你可以如果loginProcessingUrl自定义
http.formLogin().loginPage("/toLogin")
.loginProcessingUrl("login")//自定义登录请求
.usernameParameter("reusername")//自定义用户账号表单名 如果前端账号密码表单不是username 和password
.passwordParameter("repassword");
http.rememberMe().rememberMeParameter("remember");
}
//认证规则
// 密码编码 passwordEncoder
//在spring Secutiry5.0+ 增加类很多加密方法~
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这是数据正常应该从数据库中读
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("leitoqing").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}