Hello, everyone. I’m Chen

This is the fourth article in the Spring Security Advance, and the previous article is as follows:

  • Actual combat! Spring Boot Security+JWT Logon authentication!
  • OAuth2.0, Spring Cloud Security integration today.
  • OAuth2.0 actual combat! Use JWT token authentication!

The article is systematic, Chen default to see this article readers have seen the early article, before the knowledge point is no longer detailed.

Today’s article focuses on some of the exceptions that you need to customize when using Spring Security in the real world.

The table of contents is as follows:

Case Service Building

This article follows the authentication and resource services of the previous article as follows:

1, authentication service oAUTH2-Auth-server-JWT

2, resource service oauth2-auth-resource-jwt

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords: 9529 access!

The authentication service is abnormal

Take a look at the correct request for a token, using password mode as an example, as shown below:

In password mode, you need to pass five parameters: user name, password, client ID, client key, and authorization type.

So the question is: what is returned if any of the arguments are passed wrong?

1. The user name or password is incorrect

If the user name or password is intentionally entered incorrectly, the following information is returned:

2. The authorization type is incorrect

Enter a nonexistent authorization type and the following information is returned:

3, client ID, secret key error

If you enter an incorrect client ID or key, the following information is displayed:

How do you feel? Isn’t it sour? Obviously, the returned information is not suitable for the front and back end interaction, so don’t worry, here is the solution

User-defined exception information of the authentication service

There are three common exceptions listed above, and the solutions actually fall into two categories:

  • The user name or password is incorrect or the authorization type is abnormal
  • The client ID and key are abnormal

Chen here for these two exceptions on the first solution, and then from the source code to explain why to do so?

1. The user name or password is incorrect or the authorization type is abnormal

Troubleshooting methods for incorrect user names, passwords, and authorization types are complex and require customization.

1. Customize prompt message and response code

This part is customized according to the needs of their own business, Chen here just gives an example, the code is as follows:

2, custom WebResponseExceptionTranslator

Need a custom exception the translator, the default is DefaultWebResponseExceptionTranslator, must be rewritten here, there is a need to implement the method, as follows:

ResponseEntity<T> translate(Exception e) throws Exception;
Copy the code

This method is based on the passed Exception to determine different exceptions to return specific information, here to determine the Exception is as follows:

  • Abnormal UnsupportedGrantTypeException: does not support the authorization type
  • InvalidGrantException: Indicates that the user name or password is incorrect

Create a WebResponseExceptionTranslator OAuthServerWebResponseExceptionTranslator implementation, the code is as follows:

3. Configure in the authentication service configuration file

Need to be custom exception translator OAuthServerWebResponseExceptionTranslator in the configuration file configuration, is very simple, one line of code.

In AuthorizationServerConfig configuration file specifies, the code is as follows:

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords: 9529 access!

4, test,

After the configuration is complete, check whether a customized message is displayed if the user name, password, or authorization type is incorrect, as follows:

5. Source tracking

Practice has, always should understand why to do so? Here’s why you should do this from a source perspective.

We know that the interface to get the token is /oauth/token. This interface is defined in the TokenEndpoint#postAccessToken() (POST request) method as shown below:

Let’s not look at the logic, usually we write interface exceptions how to handle?

@ExceptionHandler is used to specify exceptions and then handle exceptions uniformly, right?

Then look at what type of exception the above two belong to, as follows:

Whether all inherited OAuth2Exception, then tried to search search processing OAuth2Exception TokenEndpoint this class to the exception of the processor, so he found a handleException () method, as follows:

As you can see, the abnormal translator here has been in use for our custom OAuthServerWebResponseExceptionTranslator. To see what the default exception translator is, here’s the code:

See, that’s the DefaultWebResponseExceptionTranslator

Question again: why in the configuration file set up OAuthServerWebResponseExceptionTranslator will take effect?

This must see @ EnableAuthorizationServer this annotation, the source code is as follows:

Injected the AuthorizationServerEndpointsConfiguration configuration class, including injected AuthorizationEndpoint this bean, as follows:

Add the custom exception translator to the Abstract class AbstractEndpoint. TokenEndpoint inherits the abstract class and uses the exception translator as follows:

Oh, the problem solved, learn something must know its reason……………

2. The client ID and key are abnormal

This part is more complex, want to understand or need some basic, there are many solutions to solve this exception, Chen just introduced one of them, the following details.

1. Customize prompt message and response code

This part is customized according to the needs of their own business, Chen here just gives an example, the code is as follows:

2. Customize AuthenticationEntryPoint

If this AuthenticationEntryPoint is familiar, as it was introduced in the previous article, you need to customize it to return custom prompts.

Create OAuthServerAuthenticationEntryPoint, realize AuthenticationEntryPoint, rewrite the method, the code is as follows:

3, the transformation ClientCredentialsTokenEndpointFilter

ClientCredentialsTokenEndpointFilter this filter is to check the main function of client ID and secret key, the code is as follows:

There are several important parts to cover, as follows:

  • In the constructor needs to step 2 custom OAuthServerAuthenticationEntryPoint
  • Rewrite the getAuthenticationManager() method to return the AuthenticationManager in IOC
  • Rewrite the afterPropertiesSet () method for custom authentication failure, processors, successful failure processor exception message calls OAuthServerAuthenticationEntryPoint in return

4. Specify filters in the OAuth configuration file

Only need to add custom filters to the AuthorizationServerSecurityConfigurer, the code is as follows:

Part 1 is to add filters, including authenticationEntryPoint using step 2 custom OAuthServerAuthenticationEntryPoint

Part ② must note: be sure to remove this line of code, the specific reason for the source code explained.

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords: 9529 access!

5, test,

Enter the wrong secret key directly, the result is as follows:

6. Source tracking

1, when OAuthServerAuthenticationEntryPoint call?

OAuthServerAuthenticationEntryPoint this filter inherited AbstractAuthenticationProcessingFilter this abstract class, all the logic of the doFilter (), Chen simplified the key code as follows:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
    try {
        	// Call the partial tauthentication method of the subclass to get the parameters and authenticate
			authResult = attemptAuthentication(request, response);
		}
		catch (InternalAuthenticationServiceException failed) {
            / / once the certification is unusual, call unsuccessfulAuthentication method, through failureHandler processing
			unsuccessfulAuthentication(request, response, failed);
			return;
		}
		catch (AuthenticationException failed) {
            / / once the certification is unusual, call unsuccessfulAuthentication method, through failureHandler processing
			unsuccessfulAuthentication(request, response, failed);
			return;
		}
		SuccessHandler is called if the authentication succeeds
		successfulAuthentication(request, response, chain, authResult);
}
Copy the code

The key code in unsuccessfulAuthentication () this method, the code is as follows:

2. How does a custom filter work?

This is about to see AuthorizationServerSecurityConfigurer# configure () this method, there was a piece of code is as follows:

This code is to traverse the add filters to be added to the filter chain, before BasicAuthenticationFilter this filter.

Add it to the security filter chain and the filter will take effect.

3, why can’t add. AllowFormAuthenticationForClients ()?

Or in AuthorizationServerSecurityConfigurer# configure () this method, once set allowFormAuthenticationForClients is true, Will create ClientCredentialsTokenEndpointFilter, the custom of the nature.

The resource server is abnormal

After obtaining the token from the authentication service to request the resource of the resource service, there are two major exceptions involved here, as follows:

1. Invalid token

For example, if the token is incorrect or expired, the following exception message is displayed:

2. Insufficient permissions

The permission of the token is insufficient. For example, only the admin role is allowed to access the /admin interface. The following exception information is displayed:

Resource service custom exception information

The following describes how to customize the exception information for the preceding two exceptions, which is simpler than authentication service customization.

1. Invalid token

This one is simpler and also requires a custom AuthenticationEntryPoint. The steps are as follows:

1. Customize AuthenticationEntryPoint

This is similar to the client exception of the authentication service, which is not detailed here, but directly paste the code as follows:

2. In the OAuth configuration file

This is relatively simple, directly in the configuration file can be configured, the code is as follows:

3, test,

If you access the resource service with the invalid token, you can see that the customized message has returned normally, as follows:

Source code and authentication services similar, their breakpoints try, or very simple.

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords: 9529 access!

2. Insufficient permissions

This unusual customization is more simple, Chen in the first article: combat! Spring Boot Security+JWT Logon authentication! Introduced, the following simple paste code.

1. Customize AccessDeniedHandler

The code is as follows:

2. In the OAuth configuration file

In the same method as the token invalidation exception configuration, the code is as follows:

3, test,

When you access the /admin interface, the following message is displayed:

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords: 9529 access!