Springboot进阶-02-SpringSecurity
1.Springboot-SpringSecurity
-
SpringSecurity概念
- SpringSecurity核心功能认证、授权和攻击防护。
- SpringSecurity主要通过一组过滤器链来实现。
-
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- thymeleaf和springsecurity5整合,thymeleaf可以直接通过sec来操作security -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
- 授权
- antMatchers()和hasRole()设置方式访问路径需要的角色。
- formLogin(),没有权限会进入登录页面。
- loginPage("/login"),自定义登录页面。当访问
/login
时,通过controller跳转到登录页面。 - loginProcessingUrl("/mylogin1"),默认是
/login
,只有页面登录提交的路径和loginProcessingUrl()保持一致时,SpringSecurity才会进行授权。 - successForwardUrl("/index02"),登录后转发到
/index02
。 - logoutSuccessUrl("/index"),退出登录转发到
/index
。
// 开启SpringSecurity的功能
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// / 直接放行
.antMatchers("/").permitAll()
// /test1/** 需要是test1角色才可以访问
.antMatchers("/test1/**").hasRole("test1")
.antMatchers("/test2/**").hasRole("test2")
.antMatchers("/test3/**").hasRole("test3");
// 没有权限会跳到登录页面
http.formLogin()
// 设置登录时传递的用户名和密码的参数名,默认为username和password
.usernameParameter("username").passwordParameter("password")
// 点击登录按钮后,会将请求提交到/index02,但是/index02不能接受到请求,会被重定向到 /
// 实际提交的地址为 /login,然后重定向到 /
//.loginProcessingUrl("/index02");
// 点击登录按钮后,先将登录的post请求提交给/login,然后转发给 /index02 所以浏览器地址栏URL不会改变
//.successForwardUrl("/index02");
// 自定义登录页面,定义登录访问的url为/login,然后跳转到 login.html。
// 只有登录提交的URL为和loginProcessingUrl("/mylogin1")保持一致时,successForwardUrl才有效。
// 只有登录提交的URL为和loginProcessingUrl("/mylogin1")保持一致时,SpringSecurity才会做安全的认证,适用于自定义登录页面。
// loginProcessingUrl,默认是 /login;successForwardUrl 默认时 /。
.loginPage("/login").loginProcessingUrl("/mylogin1").successForwardUrl("/index02");
// csrf 跨站请求伪造
//http.csrf().disable();
// 注销之后会默认跳转到security的/login页面,
// 通过设置logoutSuccessUrl()来改变默认要跳转的页面。
http.logout().logoutSuccessUrl("/index");
// 开启记住我
http.rememberMe();
}
}
- 认证
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 认证
* 认证时需要对密码进行加密,否则报错 There is no PasswordEncoder mapped for the id "null"
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 从内存中获取用户名、密码和角色。
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root1").password(new BCryptPasswordEncoder().encode("123456")).roles("test1").and()
.withUser("root2").password(new BCryptPasswordEncoder().encode("123456")).roles("test2").and()
.withUser("root3").password(new BCryptPasswordEncoder().encode("123456")).roles("test3");
}
}
- SpringSecurity和Thymeleaf
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
# 命名空间
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<!-- 官方建议使用 xmlns:sec="http://www.thymeleaf.org/extras/spring-security" 引入sec。
如果使用xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5",会直接报错,没有提示。-->
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<!-- 角色判断,只有是test1角色是才显示 -->
<div sec:authorize="hasRole('test1')">
<a th:href="@{/test1/1}">1-1</a>
</div>
<br>
<div sec:authorize="hasRole('test2')">
</div>
<br>
<div sec:authorize="hasRole('test3')">
<a th:href="@{/test3/1}">3-1</a>
</div>
<br>
<!-- 没有登录时才会显示登录 -->
<div sec:authorize="!isAuthenticated()">
<span>登录</span>
</div>
<br>
<!-- 登录了就显示用户名 -->
<div sec:authorize="isAuthenticated()">
<!-- 显示用户名 -->
<span sec:authentication="name"></span>
<br>
<!-- 显示登录用户的角色,test2角色显示为[ROLE_test2] -->
<span sec:authentication="principal.authorities"></span>
</div>
<br>
<!-- 登录了,才显示注销。 -->
<!-- 注销用户 -->
<div sec:authorize="isAuthenticated()">
<a th:href="@{/logout}">注销</a>
</div>
</body>
</html>