认证授权
1、PasswordEncoder
密码解析器介绍
1 |
|
2、认证授权
2.1、登录实现类(手动构造Service层)
1 |
|
2.2、SpringSecurity的配置类
antMatchers里面传ant表达式:
- ?:匹配一个字符
- *:匹配0个或多个字符
- **:匹配0个或多个目录SpringSecurity的配置类
1
2
3
4// 放行js以及css文件夹下的所有文件:
antMatchers("/js/**", "/css/**").permitAll()
// 放行所有js文件
antMatchers(”/**/*/.js").permitAll()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53// 拦截器:使用aop横切进去,所以不改变原来的代码
// 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private UserServiceImpl userService;
private PersistentTokenRepository tokenRepository;
protected void configure(HttpSecurity http) throws Exception {
// 表单登录
http.formLogin()
// 自定义登录页面(没有权限的话,让用户跳转到登录页)
.loginPage("/login.html")
// 执行自定义登录逻辑:UserServiceImpl里的LoadUserByUsername
.loginProcessingUrl("/login")
// 登录成功后跳转的页面(这个请求必须是Post方式)
.successForwardUrl("/toMain")
// 登录失败后跳转的页面(这个请求必须是Post方式)
.failureForwardUrl("/toError");
// 定制 认证、授权规则
http.authorizeRequests()
// 登录页 所有人都能访问
.antMatchers("/login.html").permitAll()
// 失败页 所有人都能访问
.antMatchers("/error.html").permitAll()
// 放行js以及css文件夹下的所有文件
.antMatchers("/js/**", "/css/**").permitAll()
// 放行image下的所有文件 (需要是POST请求)
.antMatchers(HttpMethod.POST, "/image/**").permitAll()
// author.html页面必须要有”vip1“ 或 “vip1”权限才能访问
.antMatchers("/author.html").hasAnyAuthority("vip1", "vip2")
// author.html页面必须要有”admin“角色才能访问
.antMatchers("/author.html").hasAnyRole("admin")
// 只有指定ip才能访问
// .antMatchers("/author.html").hasIpAddress("");
// 所有请求必须通过认证(登录)才能访问
.anyRequest().authenticated();
// 关闭csrf防护
http.csrf().disable();
}
//
public PasswordEncoder pw() {
return new BCryptPasswordEncoder();
}
}
3、添加 RememberMe
记住我功能
3.1、前端页面设置
只需要在登录表单中配置记住我的字段,字段值必须为remember-me
。(这个是默认的,可以更改)
SpringSecurity会自动把用户信息存储到数据源中。
1 | <form action="/login" method="post"> |
3.2、后端配置类设置 添加相应配置
1 | // 开启WebSecurity模式 |
4、按钮展示
4.1、引入命名空间依赖
1 | <!--thymeleaf与springsecurity5的组合依赖--> |
4.2、在html中引入命名空间
1 | <html xmlns="http://www.w3.org/1999/xhtml" |
4.4、按钮设置、属性获取
可以在html页面中通过sec:authentication=""
获取。UsernamePasswordAuthenticationToken
中所有getXXX
的内容,包含父类中的getXXX
的内容。
根据源码得出以下属性:
name
:登录账号名称principal
:登录主体,在自定义登录逻辑中是UserDetails
credentials
:凭证authorities
:权限和角色details
:实际上是WebAuthenticationDetails
的实例。可以获取remoteAddress
(客户端ip)和sessionId
(当前用户sessiionId
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
登录账号:<span sec:authentication="name"></span><br/>
登录账号:<span sec:authentication="principal.username"></span><br/>
凭证:<span sec:authentication="credentials"></span><br/>
角色和权限:<span sec:authentication="authorities"></span><br/>
客户端地址:<span sec:authentication="details.remoteAddress"></span><br/>
sessionId:<span sec:authentication="details.sessionId"></span><br/>
<br/>
<br/>
<br/>
通过权限判断要展示什么按钮:
<button sec:authorize="hasAuthority('vip1')">新增</button>
<button sec:authorize="hasAuthority('vip1')">删除</button>
<button sec:authorize="hasAuthority('vip2')">修改</button>
<button sec:authorize="hasAuthority('vip3')">查看</button>
<br/>
通过角色判断要展示什么按钮:
<button sec:authorize="hasRole('root')">新增</button>
<button sec:authorize="hasRole('admin')">删除</button>
<button sec:authorize="hasRole('root')">修改</button>
<button sec:authorize="hasRole('admin')">查看</button>
</body>
</html>
4.CSRF
4.1、什么是CSRF
CSRF(Cross Site Request Forgery)跨站请求伪造,通过伪造用户请求来非法访问受信任的站点。
跨域:只要网络协议、IP地址、端口中任何一个不相同就是跨域请求。
客户端与服务器进行交互时,由于http是无状态协议,所以引入cookie来记录客户端身份。在cookie中会存放sessionId用来识别客户端身份。在跨域情况下,sessionId可能被第三方劫持,
通过这个sessionId向客户端发起请求,客户端会认为这个请求是合法的,可能会发生意想不到的事情。
4.2、SpringSecurity中的CSRF
从SpringSecurity4开始,CSRF防护默认开启。默认会拦截请求,进行CSRF处理。CSRF为了保证不是其他第三方网站访问,要求
访问时携带参数名为_csrf
,值为token的内容,如果此token和服务的为其生成的token一致,则访问成功。