当前位置: 首页 > 知识库问答 >
问题:

Spring Security性:反序列化请求主体两次(oauth2处理)

蒋波光
2023-03-14
public interface TokenExtractor {

/**
 * Extract a token value from an incoming request without authentication.
 * 
 * @param request the current ServletRequest
 * @return an authentication token whose principal is an access token (or null if there is none)
 */
Authentication extract(HttpServletRequest request);
}

然而,更复杂的是,请求体还包含处理所需的其他参数,因此我希望将其反序列化为传递到控制器中的DTO类,如下所示:

@RequestMapping("/oauth/someresource")
@Transactional
public Map<String, String> resource(@AuthenticationPrincipal UserDetails userDetails,
                                     @RequestBody ClientRequestDto clientRequestDto) {
// Do some processing based on the request dto
}

我尝试在令牌提取器中手动反序列化请求,但随后得到一个错误“java.lang.IllegalStateException:getReader()已经被调用用于此请求”。

我集思广益地想出了一些我可以研究的可能的解决方案,到目前为止我已经想出了:

    null

共有1个答案

勾炳
2023-03-14

因此,我最终发现了另一个解决这个问题的问题,这是我在发布之前没有看到的(我如何在Spring的'HandlerMethodArgumentResolver'中多次读取请求体?)。其中一个还建议在HttpServletRequest周围创建一个装饰器,因此我修改了http://www.myjavarecipes.com/how-to-read-post-request-data-twick-in-spring/中的信息,添加了针对大型请求的保护。

以下是我想出来的,以防有人有任何反馈:

public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
// We include a max byte size to protect against malicious requests, since this all has to be read into memory
public static final Integer MAX_BYTE_SIZE = 1_048_576; // 1 MB

private String _body;

public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
    super(request);
    _body = "";

    InputStream bounded = new BoundedInputStream(request.getInputStream(), MAX_BYTE_SIZE);
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(bounded));

    String line;
    while ((line = bufferedReader.readLine()) != null){
        _body += line;
    }
}

@Override
public ServletInputStream getInputStream() throws       IOException {
    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes());

    return new ServletInputStream() {
        public int read() throws IOException {
            return byteArrayInputStream.read();
        }

        @Override
        public boolean isFinished() {
            return byteArrayInputStream.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }
    };
}

@Override
public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}

我使用了以下配置:

    @Bean
FilterRegistrationBean multiReadFilter() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    MultiReadRequestFilter multiReadRequestFilter = new MultiReadRequestFilter();
    registrationBean.setFilter(multiReadRequestFilter);
    registrationBean.setOrder(SecurityProperties.DEFAULT_FILTER_ORDER - 2);
    registrationBean.setUrlPatterns(Sets.newHashSet("/path/here"));
    return registrationBean;
}
 类似资料:
  • 我正在从事一个SpringMVC项目,我需要完成的任务之一是让用户在POST请求中发送一个JSON数据字符串。我知道Spring将使用Jackson对对象反序列化JSON,但如果我尝试以下方法: 我只是返回HTTP 400错误请求(“客户端发送的请求在语法上不正确”)。 如何获取客户端作为字符串发送的原始JSON?

  • 问题内容: 从这篇博客文章中,我能够创建一个使用JSON.NET序列化的自定义WCF 。需要注意的是,它的效果很好:与一起使用并不一定能按预期工作。 这是博客文章提供的实现: 基本上,在签名是参数,该方法需要实例化。 因此,这在处理REST端点方面做得非常好: 或像这样: 但是它当前不将URI模板参数映射到方法参数,例如: 微软写在重写: 这是一个扩展点,派生的行为可以用来提供自己的IDispat

  • 问题内容: 我的问题很简单:我有以下简单的类: 我正在尝试处理以下JSON: 显然,这里存在一个问题(“ blah”无法解析为int) 以前,Jackson抛出类似org.codehaus.jackson.map.JsonMappingException的内容:无法从字符串值’blah’构造java.lang.Integer的实例:不是有效的Integer值 我同意这一点,但是我想在某个地方注册一

  • 我正在尝试实现一个Jackson反序列化器,以便在JSON发生变化时能够迁移JSON(例如,在重命名的字段中,我需要将现在不一致的JSON读入一致的JSON)。 一种方法是创建JsonDeserializer,将JSON作为适当的最终类读取,然后将其作为映射再次读取,以挑选更改。 但我似乎无法做到这一点,因为每次我读取或反序列化JSON时,支持流都会关闭。 我避免创建新的ObjectMapper,

  • 问题内容: 我如何才能序列化一个特定的属性,但又防止其反序列化回POCO?是否可以使用属性装饰特定属性? 基本上,我正在寻找一个与ShouldSerialize *方法等效的反序列化方法。 我知道我可以编写一个自定义转换器,但是这样做似乎有点过头了。 编辑: 这里还有一些背景。这背后的原因是我的课看起来像: 我需要请求的属性,但是我不希望它反序列化并触发设置程序逻辑。 问题答案: 最简单的方法是将

  • 问题内容: 我有一个像这样的课程: 我想序列化它们的列表: 当我进行序列化时,动物属性的类型信息将丢失。有没有一种方法可以某种方式安装解析器侦听器,以便在遇到列表中的每个元素时提供正确的类进行反序列化?这就是手动提供描述类类型的字符串的想法。 谢谢 问题答案: Gson项目代码库中的RuntimeTypeAdapter据说可以很好地用于多态序列化和反序列化。我认为我尚未尝试使用它。有关更多信息,请

  • 我正在尝试使用spring-kafka版本2.3.0编写kafka消费者。M2库。为了处理运行时错误,我使用SeekToSumtErrorHandler.class和DeadLetterPublishingRecoverer作为我的恢复器。这仅在我的消费者代码抛出异常时才正常工作,但在无法反序列化消息时失败。 我尝试自己实现ErrorHandler,我很成功,但使用这种方法,我自己最终编写了DLT

  • 我在Spring Kafka设置中使用Avro和模式注册表。 我想以某种方式处理,它可能在反序列化过程中引发。 我找到了以下两个资源: https://github.com/spring-projects/spring-kafka/issues/164 有人知道如何在Spring Boot中捕获吗? 我使用的是Spring Boot 2.0.2 编辑:我找到了解决办法。