SpringBoot e-Commerce project mall (35K + STAR) address: github.com/macrozheng/…
Abstract
In the development process, when we encounter problems, we often use search engines to find solutions to problems and then solve them. But some problems can not find a solution for a while, need to solve their own. Here I share the debugging skills used to solve these problems, to give you a new way to solve the problem!
Problem description
In the “I dig a long time source, finally found Oauth2 custom processing results of the best solution!” In this article, we want to customize the return result of gateway authentication failure when the JWT token expires or the signature is incorrect. The problem can be solved as easily as a single code change. But it did take a bit of work to find a solution, using the DEBUG source code to find the custom configuration provided in Spring Security and fix the problem. Here’s how I found this solution using the DEBUG source code!
To solve the process
- First we need to find an entry point, and since the problem is due to expired JWT tokens or incorrect signatures, it’s easy to imagine
RSASSAVerifier
This key class, itsverify()
If the signature is incorrect, false will be returned. If the signature is incorrect, false will be returned.
- At this time, we can check the stack information to understand the whole process of this call. It can be seen that the calls below the red box are calls in WebFlux and have no reference significance, so the call is from the earliest
NimbusReactiveJwtDecoder
Class beginning;
- Let’s search
NimbusReactiveJwtDecoder
Where is it used to find another key classServerHttpSecurity
, our security configuration at the gatewayResourceServerConfig
If Spring Security provides a custom configuration, it is probably in this class.
- Look at the
ServerHttpSecurity
We can see that it is equivalent to the WebFlux version of the Spring Security configuration;
/**
* A {@link ServerHttpSecurity} is similar to Spring Security's {@codeHttpSecurity} but for WebFlux. * It allows configuring web based security for specific http requests. By default it will be applied * to all requests, but can be restricted using {@link #securityMatcher(ServerWebExchangeMatcher)} or
* other similar methods.
**/
Copy the code
- At our gateway
ResourceServerConfig
In, we have calledServerHttpSecurity
thebuild()
Method used to generateSecurityWebFilterChain
;
- Let’s take a look at this
build()
Method does something, but the key part is that it callsOAuth2ResourceServerSpec
Of the classconfigure()
Methods;
- while
OAuth2ResourceServerSpec
Of the classconfigure()
The method is called againJwtSpec
Of the classconfigure()
Methods;
- this
JwtSpec
Objects can’t be empty because we’re inResourceServerConfig
Call theOAuth2ResourceServerSpec
Of the classjwt()
Method to create it;
JwtSpec
Of the classconfigure
The method is critical. Using filters for authentication is an old Spring Security approach to authentication, so we found the default authentication filterBearerTokenAuthenticationWebFilter
;
BearerTokenAuthenticationWebFilter
Using theOAuth2ResourceServerSpec
In theentryPoint
To handle authentication failures, implemented by default asBearerTokenServerAuthenticationEntryPoint
;
- And then we had
BearerTokenAuthenticationWebFilter
thefilter()
Method,BearerTokenServerAuthenticationEntryPoint
thecommence()
Method on the breakpoint, respectively, to verify that the call through the process, completely correct;
- This means that we can simply replace the default authentication failure handler with our own custom one, directly through the following code
OAuth2ResourceServerSpec
In theentryPoint
To set it to custom.
/** * Created by macro on 2020/6/19. */
@AllArgsConstructor
@Configuration
@EnableWebFluxSecurity
public class ResourceServerConfig {
private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// omit some code...
// Custom processing of JWT request header expiration or signature error results
http.oauth2ResourceServer().authenticationEntryPoint(restAuthenticationEntryPoint);
// omit some code...
returnhttp.build(); }}Copy the code
conclusion
I recommend using DEBUG source code to solve problems that cannot be solved at the moment. First of all, find a breakthrough, you can find a method that will be executed from some of the classes you are familiar with, and then break the point, DEBUG, find the key class from the stack information of the call, and then follow the path through these key classes can find a solution!
Project source code address
Github.com/macrozheng/…
Recommended reading
Github standard star 35K+, SpringBoot (2.3.0) e-commerce actual combat project, full set of tutorials without routine access!