- 一、部分方法介绍
- 二、流程
- 三、代码
- 四、参考文献
Spring Security 是 Spring 项目组中用来提供安全认证服务的框架。
网上相关的教程很多,也很详细。如:spring security——基本介绍(一)
这里就不过多赘述了,只写部分方法的使用及其注意点。
注:在 Security 中 方法大多为链式调用,且返回类型类名较长,故本篇文章将全程省略返回类型
一、部分方法介绍
配置类 SecurityConfig
1.1 注解、继承、重写的方法等
1.1.1 @EnableWebSecurity 注解
功能:表示该类启用了 Spring Security 的 Web 安全支持
1.1.2 configure(HttpSecurity http) 继承
功能:
SecurityConfig类最基础的方法,定义了
- 请求授权的规则
- 表单验证__登录页的配置
- 注销、记住我等功能的配置
1.1.3 configure(AuthenticationManagerBuilder auth) 继承
功能:构建一个基于内存的身份验证器
注:
- 该方法将身份信息存储在内存中
在 configure(HttpSecurity http) 中使用以下内容
1.2 请求授权的规则
1.2.1 authorizeRequests()
功能:开启通过URL授权模式
注:
- 必需的方法,写就对了
- 配合 antMatchers(String… antPatterns) 使用
1.2.2 antMatchers(String… antPatterns)
功能:指定需要授权的链接
1.2.3 permitAll()
功能:允许所有人通过调用该方法的请求
1.2.4 hasRole(String role)
功能:指定允许通过调用该方法的请求的角色
注:
- 该方法会自动向参数中的角色插入前缀 “ROLE“_
- 参数举例:USER, ADMIN
- 如果不需要前缀,可以使用 hasAuthority(String authority)
1.2.5 hasAuthority(String authority)
功能:指定允许通过调用该方法的请求的角色
注:
- 该方法与 hasRole(String role) 不同的是,它不会自动插入前缀 “ROLE“_
- 参数举例:ROLE_USER, ROLE_ADMIN
1.3 表单验证__登录页
1.3.1 formLogin()
功能:开启表单验证
注:
- 如果没有使用 loginPage(String loginPage) 指定登录页,则会生成一个默认的登录表单
1.3.2 loginPage(String loginPage)
功能:指定登录页面
注:
- 参数为 跳转到登录页面的请求
- 该方法只能出现一次
1.3.3 loginProcessingUrl(String loginProcessingUrl)
功能:指定登录页面的URL
注:
- 该方法会覆盖 loginPage(String loginPage) 中指定的 url
- 该方法可以多次出现,即指定多个 url
1.3.4 usernameParameter(String usernameParameter)
功能:执行身份验证时查找用户名的HTTP参数。默认设置是“username”
注:
- 与前端登录页填写用户名的
<input>的name属性一致
1.3.5 passwordParameter(String passwordParameter)
功能:执行身份验证时查找密码的HTTP参数。默认设置是“password”
注:
- 与前端登录页填写密码的
<input>的name属性一致
1.4 注销
1.4.1 logout()
功能:开启注销功能
1.4.2 logoutSuccessUrl(String logoutSuccessUrl)
功能:注销成功后跳转到 对应请求(参数)
1.5 记住我
1.5.1 rememberMe()
功能:开启记住我功能
1.5.2 rememberMeParameter(String rememberMeParameter)
功能:用于表示在登录时记住用户的HTTP参数
注:
- 与前端登录页记住我的
<input>的name属性一致
在 configure(AuthenticationManagerBuilder auth) 中使用以下内容
1.6 内存中的身份验证
1.6.1 inMemoryAuthentication()
功能:将内存中身份验证添加到 auth 中,并返回一个配置对象,以允许对内存中身份验证进行定制
1.6.2 passwordEncoder(PasswordEncoder passwordEncoder)
功能:指定加密方式
注:
- 参数为一个对象。
- 该对象必须继承接口
org.springframework.security.crypto.password.PasswordEncoder
1.6.3 withUser(String username)
功能:添加用户至内存中
1.6.4 password(String password)
功能:指定添加的用户的密码
注:
1.此项是必需的
1.6.5 roles(String… roles)
功能与注意点都与 hasRole(String role) 相同
1.6.6 authorities(String… authorities)
功能与注意点都与 hasAuthority(String authority) 相同
前端页面 Thymeaf
1.2.1 根据用户的角色动态显示不同的内容
在 div 中加入 sec:authorize="hasRole(String roleName)"
二、流程
2.1 自定义登录页方法执行流程
- 前端页面提交请求:/login
- 控制层接收请求:@RequestMapping(“/login”)
- 完成登录操作
- 进入Security配置类判断:
- 判断 loginPage(“/toLogin”) :参数不匹配 toLogin != login
- 判断 loginProcessingUrl(“/login”) :参数匹配,权限判断通过
三、代码
此处使用的是 狂神 的 Spring Security 教程中的演示代码,并以此为基础做了部分修改
依赖 pom.xml
<dependencies>...<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>...</dependencies>
SecurityConfig.java
package nuc.ss.config;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;// AOP:拦截器@EnableWebSecurity // 开启WebSecurity模式public class SecurityConfig extends WebSecurityConfigurerAdapter {//链式编程//授权@Overrideprotected 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().usernameParameter("username").passwordParameter("password").loginPage("/toLogin").loginProcessingUrl("/login").loginProcessingUrl("/toLogin");//注销,开启了注销功能,跳到首页http.logout().logoutSuccessUrl("/");// 防止网站工具:get,posthttp.csrf().disable();//关闭csrf功能,登录失败肯定存在的原因//开启记住我功能: cookie,默认保存两周,自定义接收前端的参数http.rememberMe().rememberMeParameter("remember");}// 认证,springboot 2.1.x 可以直接使用// 密码编码: PasswordEncoder// 在spring Secutiry 5.0+ 新增了很多加密方法@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//这些数据正常应该中数据库中读auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("kuangshen").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");}}
RouterController.java
package nuc.ss.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class RouterController {@RequestMapping({"/","/index"})public String index() {return "index";}@RequestMapping({"/login","/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;}}
login.html 核心代码
<form th:action="@{/toLogin}" method="post"><div class="field"><label>Username</label><div class="ui left icon input"><input type="text" placeholder="Username" name="username"><i class="user icon"></i></div></div><div class="field"><label>Password</label><div class="ui left icon input"><input type="password" name="password"><i class="lock icon"></i></div></div><div class="field"><input type="checkbox" name="remember"> 记住我</div><input type="submit" class="ui blue submit button"/></form>
index.html 核心代码
<div class="ui container">
<div class="ui segment" id="index-header-nav" th:fragment="nav-menu">
<div class="ui secondary menu">
<a class="item" th:href="@{/index}">首页</a>
<!--登录注销-->
<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">
<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="sign-out icon"></i> 注销
</a>
</div>
</div>
</div>
</div>
<div class="ui segment" style="text-align: center">
<h3>Spring Security Study by 秦疆</h3>
</div>
<div>
<br>
<div class="ui three column stackable grid">
<!-- 菜单根据用户的角色动态的实现 -->
<!-- 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>
<div class="column" sec:authorize="hasRole('vip2')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 2</h5>
<hr>
<div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
<div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
<div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip3')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 3</h5>
<hr>
<div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
<div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
<div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
四、参考文献
4.1
4.2
4.3 IDEA中下下来的 Spring Security 源码中的方法注释
