https://docs.spring.io/spring-security/reference/servlet/architecture.html
1.7.1.1.1. filter原生列表
ForceEagerSessionCreationFilter
- ChannelProcessingFilter
- WebAsyncManagerIntegrationFilter
- SecurityContextPersistenceFilter
- HeaderWriterFilter
- CorsFilter
- CsrfFilter
- LogoutFilter
- OAuth2AuthorizationRequestRedirectFilter
- Saml2WebSsoAuthenticationRequestFilter
- X509AuthenticationFilter
- AbstractPreAuthenticatedProcessingFilter
- CasAuthenticationFilter
- OAuth2LoginAuthenticationFilter
- Saml2WebSsoAuthenticationFilter
UsernamePasswordAuthenticationFilter
- OpenIDAuthenticationFilter
- DefaultLoginPageGeneratingFilter
- DefaultLogoutPageGeneratingFilter
- ConcurrentSessionFilter
DigestAuthenticationFilter
- BearerTokenAuthenticationFilter
BasicAuthenticationFilter
- RequestCacheAwareFilter
- SecurityContextHolderAwareRequestFilter
- JaasApiIntegrationFilter
- RememberMeAuthenticationFilter
- AnonymousAuthenticationFilter
- OAuth2AuthorizationCodeGrantFilter
- SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
- SwitchUserFilter
1.7.1.1.2. 登录方式
1.7.1.1.2.1. 表单登录
该图基于我们的SecurityFilterChain
图表。
- 首先,用户向未经授权的资源
/private
发出未经身份验证的请求。 - Spring
Security的
FilterSecurityInterceptor
通过抛出AccessDeniedException
表示未经身份验证的请求将被拒绝。 3.
由于用户没有经过身份验证,ExceptionTranslationFilter
启动启动身份验证,并使用配置的AuthenticationEntryPoint
登录页面发送重定向。在大多数情况下,AuthenticationEntryPoint
是LoginUrlAuthenticationEntryPoint
的实例。
- 然后,浏览器将请求将其重定向到的登录页面。 5.
应用程序中的内容必须呈现登录页面。
提交用户名和密码时,UsernamePasswordAuthenticationFilter
对用户名和密码进行身份验证。UsernamePasswordAuthenticationFilter
扩展了AbstractAuthenticationProcessingFilter,因此此图表看起来应该非常相似。
验证用户名和密码
该图基于我们的SecurityFilterChain
图表。
- 当用户提交用户名和密码时,
UsernamePasswordAuthenticationFilter
通过从HttpServletRequest
中提取用户名和密码来创建UsernamePasswordAuthenticationToken
,这是一种Authentication
类型 - 接下来,
UsernamePasswordAuthenticationToken
将传递到AuthenticationManager
进行身份验证。AuthenticationManager
的详细信息取决于用户信息的存储方式。 如果身份验证失败,则失败
RememberMeServices.loginFail
被调用。如果没有配置,这是禁止操作。AuthenticationFailureHandler
被调用。
4 . 如果身份验证成功,那么成功。
SessionAuthenticationStrategy
收到新登录的通知。- 身份验证设置在SecurityContextHolder上。
RememberMeServices.loginSuccess
被调用。如果记住我没有配置,这是禁止操作。ApplicationEventPublisher
发布InteractiveAuthenticationSuccessEvent
。- 调用
AuthenticationSuccessHandler
。通常,这是一个SimpleUrlAuthenticationSuccessHandler
,当我们重定向到登录页面时,它将重定向到ExceptionTranslationFilter
保存的请求。
默认情况下,Spring Security表单登录是启用的。但是,一旦提供了任何基于servlet的配置,必须显式提供基于表单的登录。最小的显式Java配置如下所示:
1.7.1.1.2.2. 基本http身份验证
https://www.rfc-editor.org/rfc/rfc7235#section-4.1
“WWW-Authenticate”标头字段指示身份验证适用于目标资源的方案和参数
1.7.1.1.2.3. 摘要认证
文摘认证的核心是一个“nonce”。这是服务器生成的值。Spring Security的nonce采用以下格式:
base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))
expirationTime: The date and time when the nonce expires, expressed in milliseconds
key: A private key to prevent modification of the nonce token
1.7.1.1.3. 密码存储
内存认证的简单存储,仅用于入门,不适合生产(反编译风险)
InMemoryUserDetailsManager
implements UserDetailsService
-
具有JDBC身份验证的关系数据库
JdbcDaoImpl
实现了UserDetailsService- 默认oracle数据库格式
CREATE TABLE USERS (
USERNAME NVARCHAR2(128) PRIMARY KEY,
PASSWORD NVARCHAR2(128) NOT NULL,
ENABLED CHAR(1) CHECK (ENABLED IN ('Y','N') ) NOT NULL
);
CREATE TABLE AUTHORITIES (
USERNAME NVARCHAR2(128) NOT NULL,
AUTHORITY NVARCHAR2(128) NOT NULL
);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_UNIQUE UNIQUE (USERNAME, AUTHORITY);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_FK1 FOREIGN KEY (USERNAME) REFERENCES USERS (USERNAME) ENABLE;
// 组模式
create table groups (
id bigint generated by default as identity(start with 0) primary key,
group_name varchar_ignorecase(50) not null
);
create table group_authorities (
group_id bigint not null,
authority varchar(50) not null,
constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);
create table group_members (
id bigint generated by default as identity(start with 0) primary key,
username varchar(50) not null,
group_id bigint not null,
constraint fk_group_members_group foreign key(group_id) references groups(id)
);
-
使用UserDetailsService自定义数据存储
-
具有LDAP身份验证的LDAP存储
1.7.1.1.3.1. 密码编码器
公共静态密码编码器创建委托密码编码器()
使用默认映射创建DelegatingPasswordEncoder
。可能会添加额外的映射,编码将更新以符合最佳实践。然而,由于DelegatingPasswordEncoder
的性质,更新不应影响用户。映射电流为:
- bcrypt
BCryptPasswordEncoder
(也用于编码)
- ldap
-
LdapShaPasswordEncoder
- MD4
-
Md4PasswordEncoder
- MD5 -
new MessageDigestPasswordEncoder("MD5")
- noop
-
NoOpPasswordEncoder
-
pbkdf2Pbkdf2PasswordEncoder
- scrypt
-
SCryptPasswordEncoder
- SHA-1 -
new MessageDigestPasswordEncoder("SHA-1")
- SHA-256 -
new MessageDigestPasswordEncoder("SHA-256")
- sha256
-
StandardPasswordEncoder
- Argon2Password(密码散列比赛获胜者)
1.7.1.1.4. 漏洞保护
-
- 同步器令牌模式,不应该在cookie传输,CSRFToken 令牌应在隐藏字段或标头添加
- 每个会话唯一
- 密码
- 不可预测(大型随机值)
- 双提交cookie
- cookie中指定SameSite属性 : Lax
、
Strict或
None。(该属性不应取代CSRF令牌,是增强)
Set-Cookie: JSESSIONID=xxxxx; SameSite=Strict Set-Cookie: JSESSIONID=xxxxx; SameSite=Lax // 参考文献 - [OWASP跨站点请求伪造(CSRF)](https://owasp.org/www-community/attacks/csrf) - [PortSwigger网络安全学院](https://portswigger.net/web-security/csrf) - [Mozilla网络安全作弊表](https://infosec.mozilla.org/guidelines/web_security#csrf-prevention) - [常见的CSRF预防误解](https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2017/september/common-csrf-prevention-misconceptions/) - [跨站点请求伪造的强大防御](https://seclab.stanford.edu/websec/csrf/csrf.pdf) - 对于Java:OWASP [CSRF Guard](https://owasp.org/www-project-csrfguard/)或[Spring Security](https://docs.spring.io/spring-security/site/docs/5.5.x-SNAPSHOT/reference/html5/#csrf) - 对于PHP和Apache:[CSRFProtector项目](https://owasp.org/www-project-csrfprotector/) - 对于AngularJS:[跨站点请求伪造(XSRF)保护](https://docs.angularjs.org/api/ng/service/$http#cross-site-request-forgery-xsrf-protection)
- 同步器令牌模式,不应该在cookie传输,CSRFToken 令牌应在隐藏字段或标头添加
-
出现的问题:
- 框架用于直接操作DOM的逃逸舱口
- React
dangerouslySetInnerHTML
,而没有对HTML进行消毒 - 未经专门验证,React无法处理
javascript:
或data:
URL - Angular的
bypassSecurityTrustAs*
函数 - 模板注入
- 过时的框架插件或组件
1.7.1.1.4.1. 预防规则
## 相关文章[¶](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#related-articles)
**XSS攻击作弊表:**
以下文章介绍了如何利用本文创建的不同类型的XSS漏洞,以帮助您避免:
- OWASP:[XSS过滤器规避作弊表](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)。
**XSS漏洞的描述:**
- 关于[XSS](https://owasp.org/www-community/attacks/xss/)漏洞的OWASP文章。
**关于XSS漏洞类型的讨论:**
- [跨站点脚本的类型](https://owasp.org/www-community/Types_of_Cross-Site_Scripting)。
**如何查看跨站点脚本漏洞的代码:**
- [OWASP代码审查指南](https://owasp.org/www-project-code-review-guide/)关于[审查跨站点脚本](https://wiki.owasp.org/index.php/Reviewing_Code_for_Cross-site_scripting)漏洞[代码](https://wiki.owasp.org/index.php/Reviewing_Code_for_Cross-site_scripting)的文章。
**如何测试跨站点脚本漏洞:**
- [OWASP测试指南](https://owasp.org/www-project-web-security-testing-guide/)关于测试跨站点脚本漏洞的文章。
- [XSS实验最小编码规则](https://wiki.owasp.org/index.php/XSS_Experimental_Minimal_Encoding_Rules)
1.7.1.1.4.2. 加密保护
- 在应用层面。 -
在数据库级别(例如,SQL Server TDE)
- 预防sql注入
- 带有参数化查询
- 正确构建的存储程序
- 允许列表输入验证
- 升级所有用户提供的输入
- 减少权限/特权
- 输入验证作为辅助防御
- 在文件系统级别(例如BitLocker或LUKS)
- 在硬件层面(例如,加密的RAID卡或SSD)
- 运输层保护
- 保密 - 防止攻击者阅读交通内容。
- 完整性 - 防止攻击者修改流量。
- 重播预防-防止攻击者对服务器重播请求。
- 身份验证-允许客户端验证他们是否连接到真实服务器(请注意,除非使用客户端证书,否则不会验证客户端的身份)。
足够安全的Diffie-Hellman参数(至少2048位)
应禁用TLS压缩,以防止漏洞(昵称CRIME),该漏洞可能允许攻击者恢复会话cookie等敏感信息。
算法
对称加密,应使用密钥至少为128位(理想情况下为256位 )和安全模式的AES作为首选算法。
非对称加密,请使用带有Curve25519等安全曲线的椭圆曲线加密(ECC)作为首选算法。如果ECC不可用,并且必须使用RSA,那么请确保密钥至少为2048位。
- 不同语言的最优算法函数
秘钥管理商、CI/CD工具
- aws kms 秘钥管理
- https://azure.microsoft.com/nl-nl/products/key-vault/
- https://cloud.google.com/secret-manager
SSRF工具和代码
[美人鱼在线编辑器](https://mermaidjs.github.io/mermaid-live-editor)和[美人鱼文档](https://mermaidjs.github.io/)。
[Draw.io在线编辑器](https://www.draw.io/)。
1.7.1.1.4.3. HTTP标头
安全头
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Frame-Options: DENY X-XSS-Protection: 1; mode=block [缓存控制](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-cache-control) [内容类型选项](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-content-type-options) [HTTP严格的传输安全性](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-hsts) [X-框架选项](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-frame-options) [X-XSS-保护](https://docs.spring.io/spring-security/reference/features/exploits/headers.html#headers-xss-protection)
1.7.1.1.4.4. HTTP请求
1.7.1.1.5. 加密器
KeyGenerators类为构建不同类型的密钥生成器提供了许多方便的工厂方法
//字节加密器 (密码块链(CBC)模式下的256位AES)
Encryptors.stronger("password","salt");
//生成秘钥
String salt=KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
// 文本加密器(加密结果作为十六进制编码字符串返回)
Encryptors.text("password","salt");
// BytesKeyGenerator
KeyGenerators.secureRandom工厂方法生成由SecureRandom实例支持的BytesKeyGenerator
1.7.1.1.6. api
Spring Security Concurrency Classes
DelegatingSecurityContextCallable
DelegatingSecurityContextExecutor
DelegatingSecurityContextExecutorService
DelegatingSecurityContextRunnable
DelegatingSecurityContextScheduledExecutorService
DelegatingSecurityContextSchedulingTaskExecutor
DelegatingSecurityContextAsyncTaskExecutor
DelegatingSecurityContextTaskExecutor
DelegatingSecurityContextTaskScheduler