Skip to content

Can not make response to Slack App if request body is already consumed #910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
baseballyama opened this issue Jan 7, 2022 · 4 comments
Closed
Labels
project:bolt question M-T: User needs support to use the project

Comments

@baseballyama
Copy link

Reproducible in:

The Slack SDK version

|    +--- com.slack.api:bolt:1.7.0
|    |    +--- com.slack.api:slack-api-model:1.7.0
|    |    +--- com.slack.api:slack-api-client:1.7.0
|    |    |    +--- com.slack.api:slack-api-model:1.7.0 (*)
|    |    \--- com.slack.api:slack-app-backend:1.7.0
|    |         +--- com.slack.api:slack-api-model:1.7.0 (*)
|    |         +--- com.slack.api:slack-api-client:1.7.0 (*)
|    +--- com.slack.api:bolt-servlet:1.7.0
|    |    +--- com.slack.api:slack-api-model:1.7.0 (*)
|    |    +--- com.slack.api:slack-api-client:1.7.0 (*)
|    |    +--- com.slack.api:slack-app-backend:1.7.0 (*)
|    |    \--- com.slack.api:bolt:1.7.0 (*)

Java Runtime version

openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment (build 17.0.1+12-39)
OpenJDK 64-Bit Server VM (build 17.0.1+12-39, mixed mode, sharing)

OS info

ProductName:    macOS
ProductVersion: 12.0.1
BuildVersion:   21A559
Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:01 PDT 2021; root:xnu-8019.41.5~1/RELEASE_ARM64_T6000

Steps to reproduce:

I will create a REPL if I need it.
But at first could you please read the below description?
If a maintainer gets the issue without REPL, I will create PR.

I'm using Spring Boot and Spring Security and JWT authentication methods.
Then Spring Security (before 5.6.0-RC1) consume request body at DefaultBearerTokenResolver.
Then ServletAdapterOps can not read a request body because it's already consumed.

Then following warning occurred.

Actually, this case is resolved at Spring Boot 5.6.0-RC1 by this PR.

But I think in other cases, possibly a request body is already consumed by something before run ServletAdapterOps
Therefore I think we should change logic like this.

Expected result:

Response something to Slack App.

Actual result:

2021-11-08 03:41:15.266 [WARN] com.slack.api.bolt.util.SlackRequestParser No request pattern detected for

Requirements

ServletAdapterOps should stop to read request body but should read from getParameterMap().

@seratch seratch added project:bolt question M-T: User needs support to use the project and removed untriaged labels Jan 7, 2022
@seratch
Copy link
Contributor

seratch commented Jan 7, 2022

Hi @baseballyama, thanks for writing in!

The reason why ServletAdapterOps needs to read the raw request body instead of its parsed Map object is to check the validity of the request signature. Please refer to https://api.slack.com/authentication/verifying-requests-from-slack to learn the details.

As you observed, if some component in your app consumes a request's body input stream plus doesn't provide a way to access the raw body, the app architecture is not suitable for running Slack app endpoints. In this case, our recommendation is to have a different app with less dependencies that is dedicated to handling incoming requests from Slack.

I hope this answers your question!

@baseballyama
Copy link
Author

Thank you for the answer!
Maybe I got it.
But just I would like to confirm once again.

So for instance, getParameterValues() method doesn't have an original request body's order.
I mean some information of a request body is dropped after parsed to Map object.
Therefore Verifier#isValid can not validate the signature properly if it uses parsed Map object.

String expected = signatureGenerator.generate(requestTimestamp, requestBody);
return requestSignature != null && expected != null && requestSignature.equals(expected);

Is this correct understanding?

Thank you!

@seratch
Copy link
Contributor

seratch commented Jan 7, 2022

@baseballyama

some information of a request body is dropped after parsed to Map object.

Any data won't be dropped. However, the order of the parameters can be different if you generate a string request body data from a parsed Map object (as you know, the order of Map elements is not guaranteed in Java). To verify x-slack-signature header value, you app needs the request's body data as-is. Thus, manipulating request body data on your end does not work.

I hope this clarifies. Can we close this issue now?

@baseballyama
Copy link
Author

However, the order of the parameters can be different

Yes. This is exactly the same as what I said.

Now I got it well👍
Thank you for taking time for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project:bolt question M-T: User needs support to use the project
Projects
None yet
Development

No branches or pull requests

2 participants