SpringSecurity
简介
SpringSecurity是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web
安全控制,对于安全控制,我们仅仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!
重要的类:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略模式
- EnableWebSecurity:开启WebSecurity模式
SpringSecurity的主要两个目标是“认证”和“授权”(控制访问)
“认证”:Authentication
“授权”:Authorization
案例实现
- 1.导入依赖
<!--springboot-SpringSecurity-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
-
2.导入静态资源目录(不关键,可以自定义)
-
创建controller,页面跳转的路由
@Controller
public class RouterController {
@RequestMapping({"/","/index","/index.html"})
public String index(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id")int id){
return "views/level1/"+id;
}
@RequestMapping("/level2/{id}")
public String level2(@PathVariable("id")int id){
return "views/level2/"+id;
}
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id")int id){
return "views/level3/"+id;
}
}
- 3.创建config(自定义SecurityConfig继承WebSecurityConfigurerAdapter)
//开启WebSecurity功能
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能也只有对应权限的人可以访问
//请求授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll() //首页所有用户都可以访问
.antMatchers("/level1/**").hasRole("vip1") //对应用户对用的授权页面
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
}
}
首页:
- 4.添加认证
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能也只有对应权限的人可以访问
//请求授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限会到登录页面,需要开启登录的页面
//Login
http.formLogin();
//防止网站攻击:get ,post
http.csrf().disable();//关闭csrf(跨站请求伪造)功能,登出失败的可能原因
//注销,开启注销功能
http.logout().logoutSuccessUrl("/");
}
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("dingjie").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
SpringSecurity自带的登录
- html前端,security和thymeleaf整合
依赖:
<!--security整合thymeleaf-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<!--xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"获取提示-->
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<!--登录注销-->
<div class="right menu">
<!--如果未登录-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
</div>
<!--如果登录:用户名,注销-->
<div sec:authorize="isAuthenticated()">
<a class="item">
用户名:<span sec:authentication="name"></span>
角色:<span sec:authentication="principal.authorities"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>
</div>
</div>
登录:
未登录:
<!--sec:authorize="hasRole('vip1')"-->
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>
......
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("dingjie").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
不同用户显示不同的页面
dingjie用户界面:
root界面:
guest游客界面:
登录页面的记住我功能
- 首页页面添加
<div class="field">
<input type="checkbox" name="remember"/>记住我
</div>
- 在SecurityConfig定制登录的页面
//没有权限会到登录页面,需要开启登录的页面
//Login
//定制登录页
http.formLogin().loginPage("/toLogin")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/login");
- 在SecurityConfig中添加remember-me功能
//开启记住我功能 cookie, 默认,自定义接收前端的参数
http.rememberMe().rememberMeParameter("remember");