如何包装 OAuth2 异常?

2024-03-28

我们有一个 REST API 使用Spring OAuth2。用户通过身份验证后,所有 JSON 响应均采用以下格式:

{"code" : 12345, "data" : "..." }

但是身份验证失败的 JSON 响应与上述格式不相符,因为这是由 Spring 处理的。

例如,如果凭据不正确,客户端会得到 HTTP 状态代码 400 和 JSON 响应如下:

{"error": "invalid_grant", "error_description": "Bad credentials" }

如果用户帐户被锁定,客户端会收到 HTTP 状态代码 400 和 JSON 响应,如下所示

{"error":"invalid_grant","error_description":"User account is locked"}

所有这一切都是因为 Spring TokenEndpoint.handleException() 正在处理与 /oauth/token 相关的异常

我想更改 OAuth2 失败的 JSON 响应以遵循第一种格式。

这是我到目前为止所尝试过的但没有成功:

  1. 使用具有最高优先顺序的 ControllerAdvice 并按所述使用 @ExceptionHandlerhere https://stackoverflow.com/questions/19498378/setting-precedence-of-multiple-controlleradvice-exceptionhandlers/20473464#20473464
  2. 按照描述实现 OAuth2ExceptionRendererhere https://stackoverflow.com/questions/15110734/customize-springsecurity-oauth-2-error-output-unauthorized/15882640#15882640
  3. 实现异常映射器
  4. 添加了一个新的 ObjectMapper 并扩展了 StdSerializer。尽管我的对象映射器已初始化,但它并未用于序列化异常。也许是因为 Spring 直接调用 MappingJackson2HttpMessageConverter 并且我的应用程序中似乎有该类的多个实例。

对上述任何一种方法或新方法的任何帮助将不胜感激。

我没试过this https://stackoverflow.com/questions/31154557/customise-oath2-token-request-to-accept-extra-data/31183131#31183131方法,因为我无法更改现有客户端的上下文路径。


如果您想处理身份验证过程,您可以设置自己的自定义身份验证管理器

<oauth:authorization-server
    client-details-service-ref="clientDetails" token-services-ref="tokenServices"
    user-approval-handler-ref="userApprovalHandler">
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password authentication-manager-ref="customAuthenticationManager" />
</oauth:authorization-server>

<authentication-manager id="customAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>

<bean id="customAuthenticationProvider"
    class="com.any.CustomAuthenticationProvider">
</bean>

创建实现的自定义身份验证提供程序AuthenticationProvider

public class UserAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
        String username = auth.getName();
        String password = token.getCredentials().toString();
        User user = userService.loadByUsername(username);
        if(user.isLocked){
            throw new UserLockedException("User is locked");
        }
        if(another.something.bad.happened){
            throw new AnotherSomethingBadHappenedException("Error");
        }

        // setup authorities
        //...

        return new UsernamePasswordAuthenticationToken(user, password, authorities);
    }


}

现在您有了自己的异常,通过使用 ExceptionMapper,您可以将身份验证过程中引发的异常转换为自定义响应消息。

您可以创建的另一个自定义是在授权过程中,通过创建扩展的自定义类ApprovalStoreUserApprovalHandler

public class CustomUserApprovalHandler extends ApprovalStoreUserApprovalHandler {

    // stripped

    @Override
    public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest,
            Authentication userAuthentication) {

        ClientDetails client = clientDetailsService
                            .loadClientByClientId(authorizationRequest.getClientId());
        // here, you have the client and the user
        // you can do any checking here and throw any exception
        authorizationRequest.setApproved(approved);
        return authorizationRequest;
    }
}

为该类创建 bean 定义

<bean id="userApprovalHandler"
    class="com.any.CustomUserApprovalHandler">
        <property name="approvalStore" ref="approvalStore" />
        <property name="requestFactory" ref="oAuth2RequestFactory" />
        <property name="clientDetailsService" ref="clientDetails" />
        <property name="useApprovalStore" value="true" />
    </bean>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何包装 OAuth2 异常? 的相关文章

随机推荐

  • RESTful WCF Web 服务 POST 问题

    我无法将参数传递给 wcf web 服务 我的网络方法 OperationContract WebInvoke Method POST ResponseFormat WebMessageFormat Json UriTemplate pla
  • 有关 SQL Server 中重音不敏感的问题 (Latin1_General_CI_AS)

    我们所有的数据库都是使用默认排序规则安装的 Latin1 General CI AS 我们计划更改排序规则 以允许客户端不区分重音地搜索数据库 问题 不区分重音的数据库有哪些负面影响 如果有的话 不区分重音的数据库是否有任何性能开销 为什么
  • 复选框不显示 Chrome - 在其他浏览器中工作

    我不确定发生了什么事 记住我 左侧应该有一个复选框 底部应该有两个测试复选框 因为我有一辆自行车 我有一辆汽车 它们在 Firefox 中显示 但在 Chrome 中不显示 我相信我有 CSS 问题 但找不到它 有人可以帮忙吗 http w
  • Python ord 函数中的多个字符

    编程初学者在这里 Python 2 7 是否有解决方法可以在 Python 的 ord 函数中使用多个字符 例如 我有一个十六进制字符串 xff x1a 我想要它的十进制值 以便我可以将其与其他十六进制字符串求和 但是 ord 只接受单个十
  • 在C中从键盘获取输入而不用“return”

    在 C Mac OS 中 如何在不按 return 的情况下从键盘获取输入 在带有终端的类 Unix 系统上 我认为 MacOS X 符合要求 那么您需要将终端设置为所谓的 cbreak 模式 重点是terminal保留数据直到按下 ret
  • 尽管导入了类,但未定义类

    我似乎遇到了一个非常令人困惑的错误 尽管导入了包含我的类的 py 文件 Python 仍然坚持认为该类实际上并不存在 testmodule py中的类定义 class Greeter def init self arg1 None self
  • 在我的 android studio 模拟器中元素相互重叠

    我是新来的Android Studio 当我创建应用程序时 所有元素都相互重叠 我不知道如何编辑这段代码 请给我详细的描述 布局编辑器和模拟器结果 布局代码
  • Spark 执行器上的对象缓存

    对于 Spark 专家来说 这是一个很好的问题 我正在处理数据map操作 RDD 在映射器函数中 我需要查找类的对象A用于处理 RDD 中的元素 由于这将在执行器上执行并创建类型的元素A 将被查找 恰好是一个昂贵的操作 我想在每个执行器上预
  • PHP:如何检查 URL 是 Youtube 还是 vimeo

    如何编写一个函数来检查提供的 URL 是 youtube 还是 vimeo 例如 我将这两个 URL 作为字符串存储在数据库中 http vimeo com 24456787 http www youtube com watch v rj1
  • 使用 groupby 和 Mean() 在 Pandas 中保留一个包含分类变量的列

    有没有办法在之后保留分类变量groupby and mean 例如 给定数据框df ratio Metadata A Metadata B treatment 0 54265 937500 B10 1 AB cmpd 01 11 10736
  • 如何在内容可编辑 iframe 内创建非内容可编辑 div?

    我需要将内容可编辑的 iframe 内的某些部分设置为不可编辑 我怎么做 下面的代码在 Chrome 中有效 但在 Firefox 中无效 一切都可以在 Firefox 中编辑 我需要复选框不可编辑 Editable text div di
  • Azure 中虚拟机和应用服务之间的 Vnet

    我不知道如何连接网络应用程序 应用服务 to a 虚拟机在蔚蓝中 我已从 Web 应用程序配置面板创建了 VNet 所有项目都是使用创建的资源管理型号 都在同一个订阅并且至少是Standard定价层 显然 Web 应用程序无法连接到 V2
  • 警告会话 0x0 服务器为空、意外错误、关闭套接字连接并尝试重新连接

    我有两个节点 每个节点上都安装了带有Mesos marathon和zookeeper的docker 这是我在主节点上的 docker compose 文件 version 3 7 services zookeeper image ubunt
  • SQL Server 锁解释

    下面是 SQL Server 2000 支持的锁列表 我对 意图 锁的实际含义有点困惑 我在网上查了一下 答案似乎有点神秘 为了进一步获得我的具体问题的答案 我希望将此问题用作 Wiki 了解每个锁的含义以及在什么情况下将获取该类型的锁 S
  • pandas.groupby 对象上尊重时间的移动平均值

    给定一个以下格式的 pandas 数据框 toy pd DataFrame id 1 2 3 1 2 3 1 2 3 date 2015 05 13 2015 05 13 2015 05 13 2016 02 12 2016 02 12 2
  • 在 JavaFX 上的按钮中加载 SVG 文件

    我在 Inkscape 中创建了一个 SVG 图像 我把它放在与我的班级相同的目录中 有没有办法加载该图像并将其转换为 SVG 路径 这背后的想法是获得该图像getClass getResource image svg toExternal
  • 如何在 Jetpack Compose 中创建垂直无限轮播?

    我正在尝试构建一个可滚动列 最好是 LazyColumn 它将在滚动到末尾后再次开始重新显示第一个项目 例如 看看这个闹钟 它将从 00 59 开始循环 然后再次从 0 开始平滑滚动 我尝试过一个普通的 LazyColumn 它会显示 58
  • 线程安全的向量和字符串容器?

    我之前发过一个问题 在嵌入式 Linux 平台上使用 std string 时出现段错误 https stackoverflow com questions 2412667 seg fault when using stdstring on
  • 获取所有Android版本中来电的电话号码

    我正在尝试获取来电的来电号码 我搜索并找到了这个在 Android 中检索来电的电话号码 https stackoverflow com questions 1853220 retrieve incoming calls phone num
  • 如何包装 OAuth2 异常?

    我们有一个 REST API 使用Spring OAuth2 用户通过身份验证后 所有 JSON 响应均采用以下格式 code 12345 data 但是身份验证失败的 JSON 响应与上述格式不相符 因为这是由 Spring 处理的 例如