认证(Authentication)和授权(Authorization)
- 认证(Authentication):验证某个用户是否是系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码,系统通过校验用户名和密码来完成认证过程。
- 授权(Authorization):发生在认证之后,指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对于一个文件来说,有的用户只能读取 ,有的用户可以修改。一般来说,系统会为不同的用户分配不同的角色,每个角色会对应一系列权限。
RBAC模型
- 系统权限控制最常使用的访问控制模型就是RBAC模型。
- RBAC即基于角色的权限访问控制(Role-Base Access Control) ,这是一种通过角色关联权限,角色又关联用户的授权方式。
- 简单的说就是一个用户拥有多个角色,每个角色又被分配若干权限。就构成了用户-角色-权限的授权模型。在这种模型中,用户与角色,角色与权限构成了多对多的关系。
- 在RBAC中,权限与角色相关联,用户通过成为适当的角色的成员而得到这些角色的权限,极大简化了权限的管理
- 通常来说,如果系统对权限控制要求比较严格的话,一般都会选择使用RBAC模型来做权限控制。
什么是SpringSecurity
- SpringSecurity是 一个功能强大且高度可定制的用户认证和用户授权框架。
- 在用户认证方面,springsecurity框架支持主流的认证方式,包括HTTP基本认证,http表单认证,http摘要认证,OpenID和LDAP等。在用户授权方面,SpringSecurity提供了基于角色的访问控制和访问控制列表(Access Control List ,ACL),可以对应用中的领域对象进行细粒度的控制。
如何使用SpringSecurity
- 在pom中导入Spring Security模块。
spring-boot-starter-security
- 编写Spring Security配置类
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.WebSecurity ConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity //开启webSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//定制请求的授权规则
@Override
protected void configure(HttpSecurity http) throws Exception {
/*
定制请求规则,请求url:'/'所有人都可以访问
请求url:'/level1/**' 有角色vip1才可以访问
请求url:'/level2/**' 有角色vip2才可以访问
.........
*/
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
/********************************************************************************************/
//开启自动配置的登录功能:如果没有权限,就会跳转到登录页面!
// /login?error 重定向到这里表示登录失败
http.formLogin()
.usernameParameter("username")// 接收登录的用户名和密码
.passwordParameter("password")
.loginPage("/toLogin")
.loginProcessingUrl("/login"); // 登陆时跳转到指定的url:/login,前提是url已经写好了,且登录页面的请求方法为post
//开启自动配置的注销的功能
http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
http.logout().logoutSuccessUrl("/"); // .logoutSuccessUrl("/"); 注销成功后会访问url:'/'
//记住我
/*springsecurity自动实现了一个cookie,登录时会带上它,当注销时,就会删除那个cookie,cookie的名字是remember-me,可以在浏览器控制台看看*/
http.rememberMe().rememberMeParameter("remember");
}
/********************************************************************************************/
//给用户相应的角色权限,用户可以从数据库或者内存中取
//定义认证规则,重写configure(AuthenticationManagerBuilder auth)方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//在内存中定义,也可以在jdbc中去拿....
//Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
//要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
//spring security 官方推荐的是使用bcrypt加密方式。
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","vip2");
}
}
SpringSecurity 整合Thymeleaf
-
SpringSecurity 整合Thymeleaf可以实现根据不同权限显示不同的内容。
步骤
- 导入maven依赖
thymeleaf-extras-springsecurity5
- 导入命名空间:
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
- 在代码中使用:
sec:authorize="isAuthenticated()":
sec:authorize="hasRole('vip1'):
用来包裹代码,如果包裹的代码当前用户没有权限访问就不显示它,反之亦然。
举例:
<!--登录注销-->
<div class="right menu">
<!--如果未登录-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/login}">
<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="address card icon"></i> 注销
</a>
</div>
</div>
面试知识点总结
- SpringSecurity 是面向切面编程AOP的体现
- https://blog.csdn.net/mmmmhello/article/details/114702063