目录
spring-security架构官方文档:https://spring.io/guides/topicals/spring-security-architecture
官方文档:https://docs.spring.io/spring-security/site/docs/5.2.3.RELEASE/reference/html5/
有什么问题,复制关键字,到文档按ctrl+f
一、security我理解包括两个方面:授权和安全
- 首先是安全,这是对于系统的外部环境来说,系统的使用对象都是内部的,但是未知的外部危险确实存在,所以系统需要考虑除了内部环境的外部安全问题(比如攻击,数据泄露)
- 内部环境是系统所了解的,但是需要保证数据的合规使用,所以通过授权、权限管控来管理使用对象。
二、理解 认证(authentication)和授权(authorization)
认证方式 | 授权书 |
---|---|
确定用户是否是他们声称的身份 | 确定用户可以和不能访问的内容 |
要求用户验证凭据(例如,通过密码,安全问题的答案或面部识别) | 验证是否通过策略和规则允许访问 |
通常在授权之前完成 | 通常在成功认证后完成 |
通常,通过ID令牌传输信息 | 通常,通过访问令牌传输信息 |
通常由OpenID Connect(OIDC)协议控制 | 通常由OAuth 2.0框架控制 |
示例:公司员工需要在访问公司电子邮件之前通过网络进行身份验证 | 示例:员工成功通过身份验证后,系统将确定允许员工访问哪些信息 |
- 如上,认证是对一个人或实体检验,确定你是谁,你的身份的真实性。
- 授权是对“谁能干什么”的管控,根据你的身份(角色)最终来确定你拥有那些权限。
三、如何设计权限管理的粒度、维度
- 所谓权限管理,就是对整个网站系统资源的控制权限分配,最为常见的是比如管理员可以看到并可以访问管理页面,但是极端一点,比如,我想要角色A可以查看某个页面,但是我不想让他看到里面的某些字段,等等
- 正所谓,你看见的都是我想让你看见的,而且,这种权限精细到不止是一张数据库表或者一个网页入口。这主要是看权限架构设计的功力了,在资源的维度上你是如何划分的,那么在权限的维度上你又是如何划分的。权限是对于资源而言的。
- 如果把资源划分到不可再划分的原子状态,然后在每个原子上附加权限控制,是不是可以做到对一切资源的权限控制。那么又如何统一的管理这诸多分布的权限点呢,关键点还是在于对资源的整体把握。资源划分越精细,就越难对资源进行概括、抽象、归类,就难以确认所有资源的存在位置和规律,因而难以清楚权限控制的落点和范围。
- 以此类推,思考下spring-security的授权(权限管理)会以什么样的粒度来控制。比如通过URL、等等
四、spring-security完成一个demo
- 1、新建一个springmvc项目,加上security的依赖
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
- 2、web.xml
<!-- DelegatingFilterProxy实现了Filter接口,当容器加载并执行它的doFilter()方法时,
doFilter()方法会根据filter名称去application容器上下文中找到名称相同的Filter对象,
然后把这个对象植入到当前DelegatingFilterProxy中的delegate属性,以后每次调用DelegatingFilterProxy过滤器,
实际上是调用delegate.doFilter(request, response, filterChain);
-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
DelegatingFilterProxy实现了Filter接口,当容器加载并执行它的doFilter()方法时,doFilter()方法会根据filter名称去application容器上下文中找到名称相同的Filter对象,然后把这个对象植入到当前DelegatingFilterProxy中的delegate属性,以后每次调用DelegatingFilterProxy过滤器, 实际上是调用delegate.doFilter(request, response, filterChain);
- 3(方式1)、applicationContext.xml(或者通过引入
<import resource="spring-security.xml" />
配置)
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
">
<!-- 放开静态资源访问权限(不会经过security过滤器链) -->
<security:http pattern="/static/**" security="none"/>
<security:http auto-config="false" entry-point-ref="authenticationEntryPoint">
<security:csrf disabled="true"/>
<security:headers>
<security:frame-options policy="SAMEORIGIN" />
</security:headers>
<!-- 放开登录提交 -->
<security:intercept-url pattern="/doLogin" access="permitAll()"/>
<!-- 只需要登录,不校验角色 --><!-- /**放到最后,按顺序 -->
<security:intercept-url pattern=