200804
SpringSecurity
安全首要考虑
Spring Security is a framework that provides authentication, authorization, and protection against common attacks. With first class support for both imperative and reactive applications, it is the de-facto standard for securing Spring-based applications.
Spring Security是一个提供身份验证、授权和针对常见攻击的保护的框架。它对命令式和反应式应用程序都提供了一流的支持,是保护基于spring的应用程序的事实标准。
web安全
web应用的安全性包括用户认证(Authentication)和用户授权(Authorization)
用户认证:验证用户是否合法,是否有权限访问该系统。username+password效验
用户授权: 是否有权限执行某个操作,crud的权限不同用户授予不同角色,有不同的能力。
Spring Security 框架都有很好的支持。在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。
SpringSecurity核心类
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
springsecurity基本使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
基本授权认证规则
/**
* @author 17566
* @Date: 2020/8/4 18:30
*/
@EnableWebSecurity //开启websecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//1.
//授权请求,链式编程,对特定请求授予特定的资源需要特定权限才能使用
//在没有角色时,只能访问/ p1,p2下的所有资源都不能访问
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/p1/**").hasRole("vip1")
.antMatchers("/p2/**").hasAnyRole("vip1","vip2");
//自动配置登录功能
// login 请求来到登录页
// login?error 重定向到这里表示登录失败
http.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginPage("自定义登录页面/toLogin")
.loginProcessingUrl("登录表单提交请求地址/login");
http.csrf().disable();
//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
//2.
//http.logout()实现注销请求,默认请求为/logout
//logoutSuccessUrl("/")注销成功跳转首页
http.logout().logoutUrl("/logout").logoutSuccessUrl("/");
//记住我
//.rememberMeParameter("remember")前端表单传入的name
http.rememberMe().rememberMeParameter("remember");
http.logout().deleteCookies("JESSIONID");
//解决中文乱码问题
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8"); filter.setForceEncoding(true);
http.addFilterBefore(filter, CsrfFilter.class);
}
/**
* 自定义认证规则
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//3.
//配置名称为user1的用户有vip1的角色权限
//admin的用户有vip1,vip2的角色权限
//.passwordEncoder(new BCryptPasswordEncoder())设置密码的编码格式
//new BCryptPasswordEncoder().encode("123")对该密码进行加密
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("user1").password(new BCryptPasswordEncoder().encode("123")).roles("vip1")
.and()
.withUser("admin").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2");
}
}
密码的加密
结合thymeleaf
.passwordEncoder(new BCryptPasswordEncoder())
<!--thymeleaf与spring的结合-->
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
<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-springsecurity5"
//判断是否已经登录
<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>
<body>
index
<form th:action="@{/logout}" method="get" >
<button type="submit" >退出</button>
</form>
<!-- springsecurity5标签的使用,是否已授权 -->
<div sec:authorize="isAuthenticated()">
<p>已登录</p >
<!-- 获取登录用户名 -->
<p>登录名:<span sec:authentication="name"></span></p >
<!-- 获取登录用户所具有的角色、菜单code -->
<p>角色权限:<span sec:authentication="principal.authorities"></span></p >
<!-- 获取登录用户名 -->
<p>Username:<span sec:authentication="principal.username"></span></p >
<!-- 获取登录的其他属性,比如密码 -->
<p>Password:<span sec:authentication="principal.password"></span></p >
<p>拥有的角色:
<!-- 角色判断,是否拥有某个角色,从authorities取值判断 -->
<span sec:authorize="hasRole('ROLE_ADMIN')">管理员</span>
<!-- 授权判断,是否拥有某种授权,从authorities取值判断 -->
<span sec:authorize="hasAnyAuthority('ROLE_ADMINISTRATOR')" >超级管理员</span>
<!-- 授权判断,是否拥有某种授权,从authorities取值判断 -->
<span sec:authorize="hasPermission('index','read')" >bbb</span>
<!-- 授权判断,是否拥有某种授权,从authorities取值判断 -->
<span sec:authorize="hasAnyAuthority('index:write')" >eeee</span>
</p >
</div>
</body>