[有书共读16]Security安全控制
Spring Boot的Security安全控制
Spring Security 是啥,能干啥。
安全框架解决主要问题
- 认证 Authentication:确认用户可以访问当前系统,即解决你是谁的问题。
- 举个例子
- 牛客的员工都可以刷门禁卡进入牛客的办公室
- 来访人员,可以通过临时卡或临时密码进入牛客的办公室
- 举个例子
- 授权 Authorization :确定用户在当前系统中是否能够执行某个***作,即用户所拥有的功能权限,即解决你能干什么的问题。
- 接上个例子
- 如果要对生产系统进行维护,则必须是牛客技术中心的dba或有相应系统管理职能的员工。
- 一般的开发人员,可以在开发环境下进行代码编写,发布。
- 如果是来宾,则一般只是接受主人的邀请进行***作。
- 接上个例子
Spring Security :是一个能够为基于Spring的企业应用系统提供安全访问控制解决方案的安全框架。
包含以下模块:来源 Spring Security项目模块和新版本新特性更新
-
Core - spring-security-core.jar
包含核心身份验证和访问控制类和接口,远程处理支持和基本配置API。包含如下顶级类包。
org.springframework.security.core
org.springframework.security.access
org.springframework.security.authentication
org.springframework.security.provisioning -
Remoting - spring-security-remoting.jar
提供与Spring Remoting的集成。主包是org.springframework.security.remoting。 -
Web - spring-security-web.jar
含过滤器和相关的网络安全基础设施代码。任何与servlet API依赖关系的东西。如果您需要Spring Security Web认证服务和基于URL的访问控制,您将需要它。主包是org.springframework.security.web。 -
Config - spring-security-config.jar
包含安全命名空间解析代码和Java配置代码。如果您使用Spring Security XML名称空间进行配置或Spring Security的Java配置支持,则需要它。主包是org.springframework.security.config。 -
LDAP - spring-security-ldap.jar
LDAP认证和供应代码。如果您需要使用LDAP身份验证或管理LDAP用户条目,则是必需的。顶级包是org.springframework.security.ldap。 -
OAuth 2.0 Core - spring-security-oauth2-core.jar
spring-security-oauth2-core.jar包含为OAuth 2.0授权框架和OpenID Connect Core 1.0提供支持的核心类和接口。使用OAuth 2.0或OpenID Connect Core 1.0的应用程序(例如,客户端,资源服务器和授权服务器)需要此功能。顶级包是org.springframework.security.oauth2.core。 -
OAuth 2.0 Client - spring-security-oauth2-client.jar
spring-security-oauth2-client.jar是Spring Security对OAuth 2.0授权框架和OpenID Connect Core 1.0的客户端支持。由利用OAuth 2.0登录和/或OAuth客户端支持的应用程序所需。顶级包是org.springframework.security.oauth2.client。 -
OAuth 2.0 JOSE - spring-security-oauth2-jose.jar
spring-security-oauth2-jose.jar包含Spring Security支持JOSE (Javascript对象签名和加密)框架。JOSE框架的目的是提供一种方法来安全的请求。它是由一组规范构成:
JSON Web Token (JWT)
JSON Web Signature (JWS)
JSON Web Encryption (JWE)
JSON Web Key (JWK)
它包含顶级包:org.springframework.security.oauth2.jwt、org.springframework.security.oauth2.jose。 -
ACL - spring-security-acl.jar
专门的domain对象ACL实现。使用安全应用于应用程序中特定的domain对象实例。顶级包是org.springframework.security.cas。 -
CAS - spring-security-cas.jar
Spring Security的CAS客户端集成。如果你想用CAS单点登录服务器来使用Spring Security Web认证。顶级包是org.springframework.security.cas。 -
OpenID - spring-security-openid.jar
OpenID Web认证支持。用于对外部OpenID服务器进行身份验证。org.springframework.security.openid。需要OpenID4Java。 -
Test - spring-security-test.jar
支持使用Spring Security进行测试。
Spring Security集成
代码:securitytest
Spring Security适配器
Spring Security为Web应用提供了WebSecurityConfigurationAdapter适配器,实现了WebSecurityConfigurer接口,提供了两个方法用于重写开发者需要的安全配置。
创建一个自定义类继承WebSecurityConfigurationAdapter,并在该类中使用@EnableWebSecurity注解,就可以通过重写config方法来配置所需要的安全配置。
- 适配器代码位于:org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //... } /** 这个方法中可以通过 HttpSecurity 的 authorizeRequests 方法定义哪些URL需要被保护、哪些不需要被保护;通过formLogin()方法定义当需要用户登录的时候,跳转到的登录页面 */ protected void configure(HttpSecurity http) throws Exception { //... }
实现类代码位于:OfficialCodes/06/securitytest/src/main/java/org/fkit/securitytest/security/AppSecurityConfigurer.java
/** * 用户授权***作 * */ @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("AppSecurityConfigurer configure() HttpSecurity 调用......"); http.authorizeRequests() // spring-security 5.0 之后需要过滤静态资源 .antMatchers("/login","/css/**","/js/**","/img/*").permitAll() .antMatchers("/", "/home").hasRole("USER") .antMatchers("/admin/**").hasAnyRole("ADMIN", "DBA") .anyRequest().authenticated() .and() .formLogin().loginPage("/login").successHandler(appAuthenticationSuccessHandler) .usernameParameter("loginName").passwordParameter("password") .and() .logout().permitAll() .and() .exceptionHandling().accessDeniedPage("/accessDenied"); }
用户认证
-
代码位于:OfficialCodes/06/securitytest/src/main/java/org/fkit/securitytest/security/AppSecurityConfigurer.java
/** * 用户认证***作 * inMemoryAuthentication 方法可以添加多个用户到内存中。 * roles添加的role名称前默认会加上ROLE_,故例子中添加的角色名称实际上是“ROLE_ADMIN”“ROLE_DBA” * 实际项目中不会这样赋值的,一般是通过数据库来进行保存用户和权限,在6.3节中将介绍jpa,mybatis,jdbc的***作。 * */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { System.out.println("AppSecurityConfigurer configureGlobal() 调用......"); // spring-security 5.0 之后需要密码编码器,否则会抛出异常:There is no PasswordEncoder mapped for the id "null" auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("fkit").password("123456").roles("USER"); auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("admin").password("admin").roles("ADMIN","DBA"); }
Spring Security 核心类
Spring Security 的验证机制
Spring Security 大体上是由一堆Filter实现的,Filter会在Spring MVC前拦截请求。Filter包括登出Filter、用户名密码验证Filter之类。Filter再交由其他组件完成细分的功能。最常见的用户名密码验证Filter会持有一个AuthenticationManager引用,其是一个验证管理器,专门负责验证。但是AuthenticationManager本身并不做具体的验证工作,其持有AuthenticationProvider集合,AuthenticationProvider才是做验证工作的组件 ,验证成功或失败之后 调用对应的Handler。
SpringBoot支持
<!-- 添加spring-boot-starter-security 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
- org.springframework.boot.autoconfigure.security.SecurityProperties.class
- org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class