Spring Security
Spring Security意义:
提供的一个安全权限控制框架,可以根据使用者的需要定制相关的角色身份和身份所具有的权限,完成黑名单操作、拦截无权限的操作。配合 Spring Boot 可以快速开发出一套完善的权限系统。
Spring Security总结:
- spring security 在web应用中是基于filter的
- spring security的入口filter就是springSecurityFilterChain。(我们自定义的SecurityConfig 会有@EnableWebSecurity注解-->会加载WebSecurityConfiguration-->会创建springSecurityFilterChain),它会被DelegatingFilterProxy委托来执行过滤任务。
- springSecurityFilterChain实际上是
FilterChainProxy
(一个filter) FilterChainProxy
里边有一个SecurityFilterChain
集合,doFIlter的时候会从其中取
新建类SecurityConfig 继承 WebSecurityConfigurerAdapter
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); } }
spring security核心组件有:SecurityContext、SecurityContextHolder、Authentication、Userdetails 和 AuthenticationManager,下面分别介绍。
SecurityContext
安全上下文,用户通过Spring Security 的校验之后,验证信息存储在SecurityContext中,主要作用获取Authentication
对象。
public interface SecurityContext extends Serializable { /** * Obtains the currently authenticated principal, or an authentication request token. * * @return the <code>Authentication</code> or <code>null</code> if no authentication * information is available */ Authentication getAuthentication(); /** * Changes the currently authenticated principal, or removes the authentication * information. * * @param authentication the new <code>Authentication</code> token, or * <code>null</code> if no further authentication information should be stored */ void setAuthentication(Authentication authentication); }
SecurityContextHolder:
用来控制SecurityContext实例的。 其作用就是存储当前认证信息。
在Spring Security中,在请求之间存储SecurityContext
的责任落在SecurityContextPersistenceFilter
上 我们通常能看到类似如下的代码:
SecurityContextHolder.getContext().setAuthentication(token);
Authentication:
在Spring Security 中Authentication用来表示当前用户是谁,一般来讲你可以理解为authentication就是一组用户名密码信息。Authentication也是一个接口,其定义如下:
public interface Authentication extends Principal, Serializable { Collection<? extends GrantedAuthority> getAuthorities();//获取用户权限,一般情况下获取到的是用户的角色信息。 Object getCredentials(); //获取证明用户认证的信息,通常情况下获取到的是密码等信息。 Object getDetails();// 获取用户的额外信息,(这部分信息可以是我们的用户表中的信息) Object getPrincipal();// 获取用户身份信息,在未认证的情况下获取到的是用户名,在已认证的情况下获取到的是 UserDetails (UserDetails也是一个接口,里边的方法有getUsername,getPassword等)。 boolean isAuthenticated(); //获取当前 Authentication 是否已认证。 void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException; //设置当前 Authentication 是否已认证(true or false) }
UserDetails:
其存储的就是用户信息,其定义如下:
public interface UserDetails extends Serializable { Collection<? extends GrantedAuthority> getAuthorities(); //获取用户权限,本质上是用户的角色信息。 String getPassword(); //获取密码 String getUsername(); //获取用户名 boolean isAccountNonExpired();// 账户是否过期。 boolean isAccountNonLocked();//账户是否被锁定。 boolean isCredentialsNonExpired();//密码是否过期。 boolean isEnabled();// 账户是否可用。 }
UserDetailsService:
UserDetailsService也是一个接口,且只有一个方法loadUserByUsername
,他可以用来获取UserDetails。
我们会自定义一个CustomUserDetailsService来实现UserDetailsService接口,并实现其public UserDetails loadUserByUsername(final String login);
方法。
我们在实现loadUserByUsername
方法的时候,就可以通过查询数据库(或者是缓存、或者是其他的存储形式)来获取用户信息,然后组装成一个UserDetails
AuthenticationManager:
作用就是校验Authentication
,如果验证失败会抛出AuthenticationException
异常。AuthenticationException
是一个抽象类,因此代码逻辑并不能实例化一个AuthenticationException异常并抛出,实际上抛出的异常通常是其实现类,如DisabledException
,LockedException
,BadCredentialsException
等。BadCredentialsException
可能会比较常见,即密码错误的时候。
public interface AuthenticationManager { Authentication authenticate(Authentication authentication) throws AuthenticationException; }
通常我们的系统流程是这样的:
- 客户端(react前端,IOS,安卓)调用“登录接口”获得一个包含token的响应(通常是个JSON,如 {"token":"abcd","expires":1234567890})
- 客户端获取数据,并携带 token参数。
- 服务端根据token发现token过期/错误,返回"请登录"状态码
- 服务器发现token正常,并解析出来是A,返回A的数据。
- ……
如果我们想在spring security项目中使用自定义的token,那么我们需要思考下面的问题:
- 怎么发token(即怎么登录?)
- 发token怎么和spring security整合。
- spring security怎么根据token得到授权认证信息。
摘抄:逃离沙漠:https://www.cnblogs.com/demingblog/ 用于笔记学习,侵删