拦截关键的两个异常,对异常进行处理。主要应用异常则跳转至cas服务端登录页面

ExceptionTranslationFilter#doFilter-逻辑入口

具体操作逻辑如下

  1. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
  2. throws IOException, ServletException {
  3. HttpServletRequest request = (HttpServletRequest) req;
  4. HttpServletResponse response = (HttpServletResponse) res;
  5. //这里直接放行,看出来其主要处理的是异常发生的情况
  6. try {
  7. chain.doFilter(request, response);
  8. logger.debug("Chain processed normally");
  9. }
  10. //IO异常直接抛出
  11. catch (IOException ex) {
  12. throw ex;
  13. }
  14. catch (Exception ex) {
  15. //提取发生的异常
  16. Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex);
  17. //首先获取是否含有AuthenticationException异常
  18. RuntimeException ase = (AuthenticationException) throwableAnalyzer
  19. .getFirstThrowableOfType(AuthenticationException.class, causeChain);
  20. if (ase == null) {
  21. //没有AuthenticationException异常则尝试获取AccessDeniedException异常
  22. ase = (AccessDeniedException) throwableAnalyzer.getFirstThrowableOfType(
  23. AccessDeniedException.class, causeChain);
  24. }
  25. if (ase != null) {
  26. //处理指定的这两个关键异常
  27. handleSpringSecurityException(request, response, chain, ase);
  28. }
  29. else {
  30. //如果关键异常都没有则直接抛出
  31. if (ex instanceof ServletException) {
  32. throw (ServletException) ex;
  33. }
  34. else if (ex instanceof RuntimeException) {
  35. throw (RuntimeException) ex;
  36. }
  37. throw new RuntimeException(ex);
  38. }
  39. }
  40. }

由以上代码我们只需要着重分析下handleSpringSecurityException()方法即可

ExceptionTranslationFilter#handleSpringSecurityException-处理spring安全异常

源码如下

  1. private void handleSpringSecurityException(HttpServletRequest request,
  2. HttpServletResponse response, FilterChain chain, RuntimeException exception)
  3. throws IOException, ServletException {
  4. if (exception instanceof AuthenticationException) {
  5. //转发请求至cas服务端登录页面
  6. sendStartAuthentication(request, response, chain,
  7. (AuthenticationException) exception);
  8. }
  9. else if (exception instanceof AccessDeniedException) {
  10. //首先判断是否Authentication凭证是否为AnonymousAuthenticationToken
  11. if (authenticationTrustResolver.isAnonymous(SecurityContextHolder
  12. .getContext().getAuthentication())) {
  13. //对AnonymousAuthenticationToken类型的请求转发cas服务端登录请求页面
  14. sendStartAuthentication(
  15. request,
  16. response,
  17. chain,
  18. new InsufficientAuthenticationException(
  19. "Full authentication is required to access this resource"));
  20. }
  21. else {
  22. //对于非AnonymousAuthenticationToken类型的请求,比如UsernamePasswordAuthenticationToken/CasAuthenticationToken则直接将异常信息写出到页面
  23. accessDeniedHandler.handle(request, response,
  24. (AccessDeniedException) exception);
  25. }
  26. }
  27. }

紧接着我们看ExceptionTranslationFilter#sendStartAuthentication()方法

  1. protected void sendStartAuthentication(HttpServletRequest request,
  2. HttpServletResponse response, FilterChain chain,
  3. AuthenticationException reason) throws ServletException, IOException {
  4. //转发前先清楚凭证信息
  5. SecurityContextHolder.getContext().setAuthentication(null);
  6. requestCache.saveRequest(request, response);
  7. //通过AuthenticationEntryPoint对象转发请求,常见为CasAuthenticationEntryPoint
  8. authenticationEntryPoint.commence(request, response, reason);
  9. }

CasAuthenticationEntryPoint#commence-cas服务端登录请求转发

直接查看源码,代码很简单

  1. public final void commence(final HttpServletRequest servletRequest,
  2. final HttpServletResponse response,
  3. final AuthenticationException authenticationException) throws IOException,
  4. ServletException {
  5. //创建service回调参数路径
  6. final String urlEncodedService = createServiceUrl(servletRequest, response);
  7. //cas服务端登录请求路径拼装,即后面会添加service参数
  8. final String redirectUrl = createRedirectUrl(urlEncodedService);
  9. //模板方法,供子类复写
  10. preCommence(servletRequest, response);
  11. //直接转发
  12. response.sendRedirect(redirectUrl);
  13. }

CasAuthenticationEntryPoint以下属性必须配置

  1. loginUrl-cas服务端的登录地址,比如https://www.examplecasserver.com/cas/login
  2. ServiceProperties-回调路径的配置,主要是service属性,此处一般为应用的主页地址

小结

  1. ExceptionTranslationFilter的执行逻辑比较简单,主要是接受AccessDeniedExceptionAuthenticationException两大请求,并最终转发至cas服务端登录界面

  2. ExceptionTranslationFilter的搭档是FilterSecurityInterceptor,其介绍可查看>>>Springboot security cas源码陶冶-FilterSecurityInterceptor

  3. Note:CasAuthenticationEntryPoint在配置service回调地址时,不可为应用的登录请求地址,不然会提前被CasAuthenticationFilter拦截直接输出错误至页面了

Springboot security cas源码陶冶-ExceptionTranslationFilter的更多相关文章

  1. Springboot security cas源码陶冶-CasAuthenticationFilter

    Springboot security cas整合方案中不可或缺的校验Filter类或者称为认证Filter类,其内部包含校验器.权限获取等,特开辟新地啃啃 继承结构 - AbstractAuthen ...

  2. Springboot security cas源码陶冶-FilterSecurityInterceptor

    前言:用户登录信息校验成功后,都会获得当前用户所拥有的全部权限,所以对访问的路径当前用户有无权限则需要拦截验证一发 Spring security过滤器的执行顺序 首先我们需要验证为啥FilterSe ...

  3. Springboot security cas整合方案-原理篇

    前言:网络中关于Spring security整合cas的方案有很多例,对于Springboot security整合cas方案则比较少,且有些仿制下来运行也有些错误,所以博主在此篇详细的分析cas原 ...

  4. Springboot security cas整合方案-实践篇

    承接前文Springboot security cas整合方案-原理篇,请在理解原理的情况下再查看实践篇 maven环境 <dependency> <groupId>org.s ...

  5. Spring-shiro源码陶冶-DelegatingFilterProxy和ShiroFilterFactoryBean

    阅读源码有助于陶冶情操,本文旨在简单的分析shiro在Spring中的使用 简单介绍 Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能 web.xml配置Shiro环 ...

  6. 修改CAS源码是的基于DB的认证方式配置更灵活

    最近在做CAS配置的时候,遇到了数据源不提供密码等数据的情况下,怎样实现密码输入认证呢? 第一步:新建Java项目,根据假面算法生成CAS加密工具 出于保密需要不提供自定义的加密工具,在您的实际项目中 ...

  7. Spring Security 解析(七) —— Spring Security Oauth2 源码解析

    Spring Security 解析(七) -- Spring Security Oauth2 源码解析   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因 ...

  8. Spring-shiro源码陶冶-DefaultFilter

    阅读源码有助于陶冶情操,本文旨在简单的分析shiro在Spring中的使用 简单介绍 Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能 Apache Shiro自带的 ...

  9. SpringBoot自动配置源码调试

    之前对SpringBoot的自动配置原理进行了较为详细的介绍(https://www.cnblogs.com/stm32stm32/p/10560933.html),接下来就对自动配置进行源码调试,探 ...

随机推荐

  1. hihoCoder #1043 : 完全背包(板子题)

    #1043 : 完全背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的 ...

  2. [bzoj1706] [usaco2007 Nov]relays 奶牛接力跑

    大概是叫倍增Floyd? 显然最多200个点...f[i][j][k]表示从j到k,走2^i步的最小路程.就随便转移了.. 查询的话就是把n二进制位上是1的那些都并起来. #include<cs ...

  3. NowCoderWannafly挑战赛5-可编程拖拉机比赛-向上取整和向下取整函数

    可编程拖拉机比赛 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 65536K,其他语言131072K64bit IO Format: %lld 题目描述 "这个比赛,归根结底 ...

  4. '<<' '|' '>>' 等位运算符 课本祥解

    a<<1   相当于a*2     a>>1    相当于a/2   a<<|1   相当于a*2+1 一些算法用得到.

  5. win10系统下如何用命令行的方式打开画图软件

    按 win + r 后输入命令 mspaint  再 回车 即可!如下图所示:

  6. c++(选择排序)

    选择排序是和冒泡排序差不多的一种排序.和冒泡排序交换相连数据不一样的是,选择排序只有在确定了最小的数据之后,才会发生交换.怎么交换呢?我们可以以下面一组数据作为测试: 2, 1, 5, 4, 9 第一 ...

  7. JAVA代码实现嵌套层级列表,POI导出嵌套层级列表

    要实现POI导出EXCEL形如 --A1(LV1) ----B1(LV2) ----B2(LV2) ------C1(LV3) ------C2(LV3) ----B3(LV2) --A1(LV1)

  8. Java简历与面试

    尊重原创:http://blog.csdn.net/love_java_cc/article/details/78292347 Java就业指导   想要成为合格的Java程序员或工程师到底需要具备哪 ...

  9. putty怎么用?如何使用Putty远程管理Linux主机

    Putty是一个免费的Windows 32平台下用于telnet.rlogin和ssh客户端的远程客户端工具,可以通过PUTTY快速的实现SSH连接linux等主机,下面小编就给大家演示一下如何使用P ...

  10. dedecms 下载时弹出提示登录框或直接下载

    http://jingyan.baidu.com/article/9f63fb918656c2c8400f0ebc.html DEDECMS 默认下载 是直接给出了一个  本地下载的   下载链接 本 ...