(一) ExceptionTranslationFilter
Spring-security的异常拦截器:这个拦截器只拦截AuthenticationException和AccessDeniedException异常,其他异常直接抛出
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { chain.doFilter(request, response); logger.debug("Chain processed normally"); } catch (IOException ex) { 若捕获IOException直接抛出 throw ex; } catch (Exception ex) { // Try to extract a SpringSecurityException from the stacktrace Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex); //获取认证异常 RuntimeException ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain); if (ase == null) { //若没有找到认证异常,就找授权异常 ase = (AccessDeniedException)throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain); } if (ase != null) { //处理spring-security抛出的异常 //1. 若是认证异常交给AuthenticationEntryPoint处理 //2. 若是授权异常交给AccessDeniedHandler处理 handleSpringSecurityException(request, response, chain, ase); } else { //省略… 抛出其他异常 } } }
AuthenticationEntryPoint
当用户请求了一个受保护的资源,但是用户没有通过认证,那么抛出异常,AuthenticationEntryPoint. Commence(..)就会调用
public interface AuthenticationEntryPoint { void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException; }
LoginUrlAuthenticationEntryPoint :跳转到登录页面
SavedRequest & RequestCache
在用户还为通过认证,访问了需要认证的资源,那么spring-security会保存当前的request,然后跳转到登录界面进行认证,在认证通过后,spring-security会跳转到保存的request;这个功能就是通过SavedRequest 和RequestCache 接口
1. SavedRequest:保存request的所有信息,默认的实现是DefaultSavedRequest
public interface SavedRequest extends java.io.Serializable { String getRedirectUrl(); List<Cookie> getCookies(); String getMethod(); List<String> getHeaderValues(String name); Collection<String> getHeaderNames(); List<Locale> getLocales(); String[] getParameterValues(String name); Map<String,String[]> getParameterMap(); }
2. RequestCache:默认的实现HttpSessionRequestCache,保存SavedRequest到session,
可以自己设置RequestMatcher,默认是AnyRequestMatcher
public interface RequestCache { void saveRequest(HttpServletRequest request, HttpServletResponse response); SavedRequest getRequest(HttpServletRequest request, HttpServletResponse response); HttpServletRequest getMatchingRequest(HttpServletRequest request, HttpServletResponse response); void removeRequest(HttpServletRequest request, HttpServletResponse response); }
AccessDeniedHandler
用户已经通过了认证,在访问一个受保护的资源,但是权限不够,那么抛出异常,AccessDeniedHandler. Handle(..)会调用
AccessDeniedHandlerImpl:若用户配置了权限不足的错误页面,那么就会跳转到错误页面;
若没有配置,那么就返回一个403
(二) SecurityContextPersistenceFilter
这个拦截器只完成两个任务:
1. 通过SecurityContextRepository获取到SecurityContext,默认是从session中获取,若没有找到,那么SecurityContextRepository就是创建一个空的,然后在通过SecurityContextHolder把获取到的SecurityContext保存到ThreadLocal
2. 在请求结束后通过SecurityContextHolder清除掉ThreadLocal中的SecurityContext
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; 确保这个拦截器一次请求只执行一次 if (request.getAttribute(FILTER_APPLIED) != null) { chain.doFilter(request, response); return; } //省略….. HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); 通过SecurityContextRepository获取SecurityContext,SecurityContextRepository默认是HttpSessionSecurityContextRepository SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { 默认SecurityContextHolder把SecurityContext保存到ThreadLocal中 SecurityContextHolder.setContext(contextBeforeChainExecution); chain.doFilter(holder.getRequest(), holder.getResponse()); } finally { SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); // Crucial removal of SecurityContextHolder contents - do this before anything else. 清除SecurityContext,保存SecurityContext到session中 SecurityContextHolder.clearContext(); repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); request.removeAttribute(FILTER_APPLIED); } } }
(三) UsernamePasswordAuthenticationFilter
处理用户登录的拦截器,继承与AbstractAuthenticationProcessingFilter。
在AbstractAuthenticationProcessingFilter中的doFilter:
public void doFilter(ServletRequest req,ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; //匹配url,通过RequestMatcher判断是否认证请求的url是指定结尾的,默认的结尾是/j_spring_security_check,所有在form表单提交的地址要以/j_spring_security_check结尾 if (!requiresAuthentication(request, response)) { chain.doFilter(request, response); return; } Authentication authResult; try { //调用子类UsernamePasswordAuthenticationFilter的attemptAuthentication方法 authResult = attemptAuthentication(request, response); if (authResult == null) { // return immediately as subclass has indicated that it hasn't completed authentication return; } sessionStrategy.onAuthentication(authResult, request, response); } catch(InternalAuthenticationServiceException failed) { // 在认证的过程中抛出了异常,那么就认证失败。 //从SecurityContextHolder清除掉SecurityContext; //AuthenticationFailureHandler处理后续操作,跳转到认证失败URL可以在security.xml中配置 //RememberMeServices 删除保存的cookie unsuccessfulAuthentication(request, response, failed); return; } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(request, response, failed); return; } // Authentication success //保存SecurityContext //RememberMeServices保存cookie //AuthenticationSuccessHandler 若有缓存到session中的URL,那么跳转,若没有,那么跳转到默认的URL,可以在security.xml中配置 successfulAuthentication(request, response, chain, authResult); }
UsernamePasswordAuthenticationFilter中的attemptAuthentication方法:
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { //判断是否是POST请求,默认是要求必须是POST if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } //从request中解析出表单提交的username password,默认的参数名称是:j_username j_password String username = obtainUsername(request); String password = obtainPassword(request); //省略…… UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); //获取到AuthenticationManager调用authenticate方法进行认证 return this.getAuthenticationManager().authenticate(authRequest); }
相关推荐
#spring-security-csrf令牌拦截器一个AngularJS拦截器,它将在HTTP请求中包含CSRF令牌标头。 它通过默认情况下对/进行AJAX HTTP HEAD调用来做到这一点,然后检索HTTP标头'X-CSRF-TOKEN'并在所有HTTP请求上设置相同...
14.1. AOP 联盟(MethodInvocation) 安全拦截器 14.1.1. 精确的MethodSecurityIterceptor 配置 14.2. AspectJ (JoinPoint) 安全拦截器 15. 基于表达式的权限控制 15.1. 概述 15.1.1. 常用内建表达式 15.2...
web|[ssh项目,spring mvc,过滤器,拦截器,监视器,thymeleaf,lombok,jquery,bootstrap,mysql](https://github.com/smltq/spring-boot-demo/blob/master/web/HELP.md) aop|[aop,正则,前置通知,后置通知,环绕通知]...
SpringMvc 拦截器 原理清楚,代码简单,值得学习!
核心 - spring-security-core.jar 25 远程处理 - spring-security-remoting.jar 25 Web - spring-security-web.jar 25 配置 - spring-security-config.jar 26 LDAP - spring-security-ldap.jar 26 ACL - spring-...
14.1. AOP联盟 (MethodInvocation) 安全拦截器 14.1.1. 精确的 MethodSecurityIterceptor 配置 14.2. AspectJ (JoinPoint) 安全拦截器 15. 基于表达式的权限控制 15.1. 概述 15.1.1. 常用内建表达式 ...
1.本项目为SpringCloud ...2.由于Gateway采用的是纯Webflux方式,所以原有的Spring基于传统拦截器、过滤器的方式无法正常使用SpringSecurity。 3.因此,本项目根据WebFlux的方式,进行了整合,实现了登录和权限验证。
它使用gRPC拦截器与Spring Security集成,并支持两种身份验证机制:HTTP Basic Auth和带有JSON Web令牌的OAuth2。 在此演示中,可能会感兴趣以下内容: 包含有关此演示的背景和动机的更多详细信息。 要求 Java 1.8...
14.1. AOP联盟 (MethodInvocation) 安全拦截器 14.1.1. 精确的 MethodSecurityIterceptor 配置 14.2. AspectJ (JoinPoint) 安全拦截器 15. 基于表达式的权限控制 15.1. 概述 15.1.1. 常用内建表达式 15.2. Web...
那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证; 二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码...
Spring Security 3.1.3配置实例
拦截器配置 @ControllerAdivce @ExceptionHandler @InitBinder @ModelAttribute 其他配置 ViewController 路径匹配参数配置 WebMvcConfigurerAdapter WebMvcConfigurer ...
它使用了spring的方式提供了安全和认证安全服务,包括使用bean context,拦截器和面向接口的编程方式。因此,acegi安全系统能够轻松地适用于复杂的安全需求。 安全涉及到两个不同的概念,认证和授权。前者是关于...
Spring Security3 拦截 过滤器 安全,框架原理入门
springboot_springsecurity_jwt_demo
Spring Security 3:使用一个简单的设置,并配置了一个 http 基本入口点,该入口点将始终返回未经授权的 http 状态(401),这将导致 angular js 拦截响应,如果检测到 401,将触发登录事件。 将触发基本身份验证,...
本项目基于Spring,整合Spring的security模块,实现用户管理和权限控制,是一套较为通用的权限控制功能,主要内容如下: 1.登录,包括“记住我”的功能; 2.加密,存储的密码不采用明文,初始密码1234; 3.拦截器...
主要给大家介绍了关于Spring boot拦截器实现IP黑名单的完整步骤,需要的朋友可以参考下
一个基于 Spring Boot 、 Spring Boot Jpa、 JWT、Spring Security、Redis、Vue、eladmin的新闻发布管理系统 **初始账号密码:** `admin / 123456` #### 主要特性 - 使用最新技术栈,社区资源丰富。 - 高效率开发...
springsecuritytest自定义权限成功实例.rar 每个类都有相应的详细的介绍,看懂不难,当前前提还是需要对Springsecurity有些了解,自定义权限拦截器;认证管理器;用户详细信息;资源访问管理;用户信息查询等类;