Spring security能够进行认证和受权,认证和受权须要针对每个请求,因此这个功能,能够用过滤器来实现,spring security正是经过一系列过滤器来实现认证和受权功能的。spring
咱们来看看其中几个比较重要的过滤器,类和接口。安全
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}session
用来记录用户的信息,包括用户名,权限等信息。ide
UserDetailsService接口用于返回用户相关数据返回的是一个UserDetails实例,它有loadUserByUsername()方法,该方法能够根据username查询用户实体,能够实现该接口覆盖该方法,实现自定义获取用户过程。加密
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}spa
封装用户信息的接口,UsernamePasswordAuthenticationToken是它的实现类,用户登陆之后,用户名,密码等信息被封装到了UsernamePasswordAuthenticationToken对象中。code
它和UserDetails不一样之处在于Authentication记录的是当前登陆用户的信息,而UserDetails则是用户信息的封装。orm
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}对象
getAuthorities方法获取权限信息的列表接口
getCredentials方法获取用户认证时输入的密码
getDetails方法获取访问者的ip地址和sessionid的值
getPrincipal方法获取用户的信息,大部分状况下返回的是UserDetails接口的实现类
是认证相关的核心接口,用来处理认证请求,若是认证成功则返回一个Authentication接口的实例,它的默认实现类是:ProviderManager。
SecurityContext:是安全上下文接口,用来存储认证受权的相关信息,这个接口只有两个方法,Authentication对象的getter、setter。
public interface SecurityContext extends Serializable {
Authentication getAuthentication();
void setAuthentication(Authentication var1);
}
保存系统当前的安全上下文,包括当前使用系统的用户的信息。
该接口有不少实现类,它用来在认证的过程当中使用matches方法比对密码,具体如何比对密码则取决于PasswordEncoder的实现类。
public interface PasswordEncoder {
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);
}
好比不对密码进行加密,采用明文字符串进行比对能够:
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
可是在实际项目中咱们每每会对密码进行加密,比较经常使用的PasswordEncoder实现类有:、
BCryptPasswordEncoder, Pbkdf2PasswordEncoder, SCryptPasswordEncoder
若是使用BcryptPasswordEncoder:
则:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
认证流程:
1.用户提交用户名密码被UsernamePasswordAuthenticationFilter 过滤器获取到,
封装为Authentication接口的实例,一般状况下是UsernamePasswordAuthenticationToken。
2.过滤器将Authentication提交至认证管理器(AuthenticationManager)进行认证,认证成功后返回一个被填充满信息的Authentication实例.
3. SecurityContextHolder保存返回的Authentication实例.
受权流程:
1.拦截请求:已认证的用户请求将会被过滤器:FilterSecurityInterceptor拦截。
2. FilterSecurityInterceptor获取访问权限,该权限就是咱们配置的访问规则如。
http
.authorizeRequests()
.antMatchers("/r/r1").hasAuthority("p1")
.antMatchers("/r/r2").hasAuthority("p2")
3. FilterSecurityInterceptor会调用访问决策管理器 AccessDecisionManager 进行受权决策,若决策经过,则容许访问资源,不然将禁止访问
AccessDecisionManager:访问决策管理器,用来控制用户是否有相应的权限。
public interface AccessDecisionManager {
/**
* 经过传递的参数来决定用户是否有访问对应受保护资源的权限
*/
void decide(Authentication authentication , Object object, Collection<ConfigAttribute>
configAttributes ) throws AccessDeniedException, InsufficientAuthenticationException;
//略..
}
参数说明:
Authentication:要访问资源的访问者
object:要访问的受保护资源
configAttributes:是受保护资源的访问策略
decide方法就是用来判断访问者是否有访问某资源的权限。
它用投票的方式来决定是否有访问某资源的权限