SpringSecurity 是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring
IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection
依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
一般后台管理系统的权限认证,都需要大量的逻辑处理验证,而SpringSecurity的出现很好的解决了这个难题,使得代码得到了很好的解耦
1.登录校验流程
1.1SpringSecurity验证流程
ExceptionTranslationFilter:处理过滤器链中抛出的任何AccessDeniedException和AuthenticationException 。
FilterSecurityInterceptor:负责权限校验的过滤器。
1.2认证具体详细流程
Authentication接口: 它的实现类,表示当前访问系统的用户,封装了用户相关信息。
AuthenticationManager接口:定义了认证Authentication的方法
UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法。
UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回。然后将这些信息封装到Authentication对象中。
登录模块
SecurityContextHolder.getContext.setAuthentication方法存储该对象
实现UserDetails类,在getAuthorties()封装权限信息
调用hasAuthority()拥有的权限信息
获取的权限信息进行比较,是否正确?
Security的配置类 是实现WebSecurityConfigurerAdapter这个类
SecurityConfig可以自行去官网,或者百度如何详细配置,很简单 configure()
AuthenticationEntryPoint
AuthenticationEntryPoint是Spring Security
Web一个概念模型接口,顾名思义,他所建模的概念是:“认证入口点”。
它在用户请求处理过程中遇到认证异常时,被ExceptionTranslationFilter用于开启特定认证方案(authentication
schema)的认证流程
自定义权限认证失败返回值
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Cache-Control","no-cache");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage())));
response.getWriter().flush();
}
}
AccessDeniedHandler
AccessDeniedHandler权限认证失败,或者无权限访问
public class RestfulAccessDeniedHandler implements AccessDeniedHandler{
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException e) throws IOException, ServletException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Cache-Control","no-cache");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
response.getWriter().flush();
}
}
动态权限过滤器,用于实现基于路径的动态权限过滤
AccessDecisionManager
动态权限决策管理器,用于判断用户是否有访问权限
在Security的config配置权限过滤
CSRF
CSRF是指跨站请求伪造(Cross-site request forgery),是web常见的攻击之一。
https://blog.csdn.net/freeking101/article/details/86537087
SpringSecurity去防止CSRF攻击的方式就是通过csrf_token。后端会生成一个csrf_token,前端发起请求的时候需要携带这个csrf_token,后端会有过滤器进行校验,如果没有携带或者是伪造的就不允许访问。
我们可以发现CSRF攻击依靠的是cookie中所携带的认证信息。但是在前后端分离的项目中我们的认证信息其实是token,而token并不是存储中cookie中,并且需要前端代码去把token设置到请求头中才可以,所以CSRF攻击也就不用担心了。
还有跨域等问题,基于注解权限控制等等,在这里没有很多的介绍,可以去官网看看
这个up主讲的真不错(https://space.bilibili.com/663528522)