浅析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());
复制代码

 

posted @   古兰精  阅读(5750)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2017-06-24 浏览器兼容性处理小技巧随手记系列(一)
点击右上角即可分享
微信分享提示