zoukankan      html  css  js  c++  java
  • 浅析SpringSecurity的AuthenticationEntryPoint认证入口点及其实现类简介及AccessDeineHandler

    一、AuthenticationEntryPoint简介

      AuthenticationEntryPoint是Spring Security Web一个概念模型接口,顾名思义,他所建模的概念是:“认证入口点”。

      它在用户请求处理过程中遇到认证异常时,被ExceptionTranslationFilter用于开启特定认证方案(authentication schema)的认证流程

      该接口只定义了一个方法:

    void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException;

      这里参数request是遇到了认证异常authException用户请求,response是将要返回给客户的相应,方法commence实现,也就是相应的认证方案逻辑会修改response并返回给用户引导用户进入认证流程。

      在该方法被调用前,ExceptionTranslationFilter会做好如下工作:填充属性HttpSession,使用属性名称为AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY

    二、AuthenticationEntryPoint源代码

    package org.springframework.security.web;
    
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.access.ExceptionTranslationFilter;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    public interface AuthenticationEntryPoint {
    
        /**
         * Commences an authentication scheme.
         * 
         * ExceptionTranslationFilter will populate the HttpSession
         * attribute named
         * AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY
         * with the requested target URL before calling this method.
         * 
         * Implementations should modify the headers on the ServletResponse as
         * necessary to commence the authentication process.
         *
         * @param request that resulted in an AuthenticationException
         * @param response so that the user agent can begin authentication
         * @param authException that caused the invocation
         *
         */
        void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException;
    }

      Spring Security Web 为AuthenticationEntryPoint提供了一些内置实现:

    1、Http403ForbiddenEntryPoint:设置响应状态字为403,并非触发一个真正的认证流程。通常在一个预验证(pre-authenticated authentication)已经得出结论需要拒绝用户请求的情况被用于拒绝用户请求。

    2、HttpStatusEntryPoint:设置特定的响应状态字,并非触发一个真正的认证流程。

    3、LoginUrlAuthenticationEntryPoint:根据配置计算出登录页面url,将用户重定向到该登录页面从而开始一个认证流程。

    4、BasicAuthenticationEntryPoint:对应标准Http Basic认证流程的触发动作,向响应写入状态字401和头部WWW-Authenticate:"Basic realm="xxx"触发标准Http Basic认证流程。

    5、DigestAuthenticationEntryPoint:对应标准Http Digest认证流程的触发动作,向响应写入状态字401和头部WWW-Authenticate:"Digest realm="xxx"触发标准Http Digest认证流程。

    6、DelegatingAuthenticationEntryPoint:这是一个代理,将认证任务委托给所代理的多个AuthenticationEntryPoint对象,其中一个被标记为缺省AuthenticationEntryPoint。

    三、自定义认证返回

    public class ExamAuthenticationEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            OperationInfo info = OperationInfo.failure("请登录后操作");
            HttpResponseUtil.setResponseMessage(response, info);
        }
    }

    1、实现 AuthenticationEntryPoint  类,覆写 commence 方法。

    2、设置ExamAuthenticationEntryPoint

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()......
        .exceptionHandling().authenticationEntryPoint(new ExamAuthenticationEntryPoint())
        ......
    }

    四、自定义AccessDeineHandler

      AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常   ——  也就是未授权的问题

      AccessDeineHandler 用来解决认证过的用户访问无权限资源时的异常  ——  也就是权限不足的问题

    public class CustomAccessDeineHandler implements AccessDeniedHandler {
        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
                AccessDeniedException accessDeniedException) throws IOException, ServletException {
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/javascript;charset=utf-8");
            response.getWriter().print(JSONObject.toJSONString(RestMsg.error("没有访问权限!")));
        }
    }
    //添加自定义异常入口,处理accessdeine异常
    http.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())
    .accessDeniedHandler(new CustomAccessDeineHandler());

    // 禁用缓存 http.headers().cacheControl(); // 添加JWT filter http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); //添加未授权处理 http.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()); //权限不足处理 http.exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
  • 相关阅读:
    IsDefined的问题
    设计匠艺模型
    真实案例引起的对系统健壮性的思考
    软件系统的稳定性
    LA工作第二周体会
    LA工作第一周体会
    https://blog.csdn.net/qq_26264237/article/details/90575165
    Maven项目配置logback
    Java 工具 Hutool4.0.0 正式发布:从懵懂到成熟
    IDEAidea中解决Java程序包不存在问题
  • 原文地址:https://www.cnblogs.com/goloving/p/14927256.html
Copyright © 2011-2022 走看看