“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”

In the previous article Springcloud Oauth2 HA, the realization of unified authentication and authorization based on Oauth2. In the configuration, we can see:

Security: oauth2: # cas-server-url: http://cas-server-service admin-web client-secret: admin-web-123 user-authorization-uri: ${cas-server-URL}/oauth/authorize # specifies the access-tok-URI required for authorization code authentication. Resource: loadBalanced: true ID: admin-web user-info-uri: ${cas-server-url}/oauth/token # ${cas-server-url}/oauth/token # ${cas-server-url}/ API /user # prefer-token-info: falseCopy the code

The URL configuration here is based on the K8S Service to achieve load balancing and high availability. But let’s look at user-info-URI next. The principle of user-info-URI is that after authentication by the authorization server, the Principal of authentication information is bound to the URL to obtain user information. Of course it also has the accompanying UserInfoTokenService and so on.

However, there are some problems when the client obtains user permissions. For example, an interface on the Web side requesting the consumer side:

/** * return all services found * @author Damon * @date 2 November 2021 8:18:44 * @return ** / @preauthorize ("hasRole('admin')") @GetMapping(value = "/getService") public String getService(){ HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity<String> formEntity = new HttpEntity<String>(null, headers); String body = ""; try { ResponseEntity<String> responseEntity = restTemplate.exchange("http://cas-server/api/v1/user", HttpMethod.GET, formEntity, String.class); if (responseEntity.getStatusCodeValue() == 200) { return "ok"; } } catch (Exception e) { System.out.println(e.getMessage()); } return body; }Copy the code

In this interface, we control permissions by adding @preauthorize (“hasRole(‘admin’)”) so that only admin users can access the interface.

We first request the authentication center login interface to obtain the token:

After getting the token, we request the interface and we find:

When requesting this interface, the consumer ends up requesting the authentication center’s interface:

2021-11-03 15:59:09.305 INFO 127896 -- [IO2-2001-exec -4] O.A.C.C.C. [Tomcat].[/] : Initializing Spring DispatcherServlet 'DispatcherServlet' 2021-11-03 15:59:09.305 INFO 127896 -- [IO2-2001-exec-4] o.s.web.servlet.DispatcherServlet : Initializing Servlet' dispatcherServlet' 2021-11-03 15:59:09.305 DEBUG 127896 - [IO2-2001-exec -4] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver 15:59:09 2021-11-03. 127896-316 the DEBUG [io2-2001 - exec - 4] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 2021-11-03 15:59:09. 127896-316 the INFO [io2-2001 - exec - 4] O.S.W eb. Servlet. DispatcherServlet: 2021-11-03 15:59:09.385 DEBUG 127896 -- [IO2-2001-exec -4] org.springframework.web.HttpLogging : HTTP GET http://cas-server/auth/user 2021-11-03 15:59:09.389 DEBUG 127896 -- [IO2-2001-exec-4] org.springframework.web.HttpLogging : Accept=[application/json, Application / * + json] 15:59:09 2021-11-03. 127896-427 the DEBUG [io2-2001 - exec - 4] org. Springframework. Web. HttpLogging: Response 404 NOT_FOUND 15:59:09 2021-11-03. 127896-446 the DEBUG [io2-2001 - exec - 4] O.S.W.C.H ttpMessageConverterExtractor : Reading to [org.springframework.security.oauth2.com mon. Exceptions. OAuth2Exception] 2021-11-03 15:59:09. WARN 456 to 127896 --- [io2-2001-exec-4] o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class org.springframework.web.client.HttpClientErrorException$NotFound, 404 : [{" timestamp ":" the 2021-11-03 T07:59:09. 423 + 00:00 ", "status" : 404, "error" : "Not Found", "message" : ""," path ":"/auth/user "}] The 2021-11-03 15:59:09. ERROR 457-127896 [io2-2001 - exec - 4] C.L.H.C ustomAuthenticationEntryPoint: Invalid token, please re-authenticate access {"data":" b34841b4-61FA-4DB-9e2B-76496deb27b4 ","result":{"code":20202," MSG ":" unauthenticated ","status":401}}Copy the code

However, if the authentication center returns a 404 status code, the EntryPoint error message is displayed: Invalid token, please re-authenticate access. Return the following body :{” data”:” b34841b4-61FA-4DB-9e2B-76496deb27b4 “,”result”:{“code”:20202,” MSG “:” unauthenticated “,”status”:401}}.

Next analysis: why did the certification authority return 404? See the certification Authority log:

The 2021-11-03 15:59:09. 54492-407 the DEBUG [15] o2-2000 - exec - O.S.W eb. Servlet. DispatcherServlet: GET "/auth/user", The parameters 15:59:09 = {} 2021-11-03. 54492-409 the DEBUG [15] o2-2000 - exec - O.S.W.S.H andler. SimpleUrlHandlerMapping: Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "Classpath: / public/"] 15:59:09 2021-11-03. 54492-413 the DEBUG [15] o2-2000 - exec - O.S.W.S.R.R esourceHttpRequestHandler: Resource not found the 2021-11-03 15:59:09. 54492-414 the DEBUG [15] o2-2000 - exec - O.S.W eb. Servlet. DispatcherServlet: Completed 404 NOT_FOUND 15:59:09 2021-11-03. 54492-422 the DEBUG [15] o2-2000 - exec - O.S.W eb. Servlet. DispatcherServlet: "ERROR" dispatch for GET "/error", The parameters = {} 2021-11-03 15:59:09. 54492-423 the DEBUG [15] o2-2000 - exec - S.W.S.M.M.A.R equestMappingHandlerMapping: Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) The 2021-11-03 15:59:09. 54492-424 the DEBUG [15] o2-2000 - exec - O.S.W.S.M.M.A.H ttpEntityMethodProcessor: Using 'application/json', given [application/json] and supported [application/json, application/*+json, application/json, application/*+json, application/json, Application / * + json] 15:59:09 2021-11-03. 54492-424 the DEBUG [15] o2-2000 - exec - O.S.W.S.M.M.A.H ttpEntityMethodProcessor: Writing [{timestamp=Wed Nov 03 15:59:09 CST 2021, status=404, error=Not Found, message=, Path = / auth/user}] 15:59:09 2021-11-03. 54492-426 the DEBUG [15] o2-2000 - exec - O.S.W eb. Servlet. DispatcherServlet: Exiting from "ERROR" dispatch, status 404Copy the code

Oauth2 has no such interface :/auth/user. Finally decided to write an interface to replace the native:

@GetMapping("/api/v1/user") public Authentication user(Map map, Principal user, Authentication auth) {// Obtain the current user information logger.info("cas-server provide user: "+ json.tojsonString (auth)); return auth; }Copy the code

After encapsulation and overwriting, configure the related configuration directly on the consumer side:

cas-server-url: http://cas-server

security:
  path:
    ignores: /,/index,/static/**,/css/**, /image/**, /favicon.ico, /js/**,/plugin/**,/avue.min.js,/img/**,/fonts/**
  oauth2:
    client:
      client-id: rest-service
      client-secret: rest-service-123
      user-authorization-uri: ${cas-server-url}/oauth/authorize
      access-token-uri: ${cas-server-url}/oauth/token
    resource:
      loadBalanced: true
      id: rest-service
      prefer-token-info: false
      user-info-uri: ${cas-server-url}/api/v1/user
    authorization:
      check-token-access: ${cas-server-url}/oauth/check_token
Copy the code

At the same time, the authentication center and the consumer end are started. After obtaining the token, the interface is requested:

Add permission to user 403 (‘ 403 ‘);

"authorities": [ { "authority": "ROLE_admin" }, { "authority": "admin" }
Copy the code

After adding, we find that we can request the interface successfully:

{ "authorities": [ { "authority": "ROLE_admin" }, { "authority": "admin" } ], "details": { "remoteAddress": "0:0:0:0:0:0:0:1", "sessionId": null, "tokenValue": "b34841b4-61fa-4dbb-9e2b-76496deb27b4", "tokenType": "bearer", "decodedDetails": null }, "authenticated": true, "userAuthentication": { "authorities": [ { "authority": "ROLE_admin" }, { "authority": "admin" } ], "details": { "authorities": [ { "authority": "ROLE_admin" }, { "authority": "Admin"}], "details": {"remoteAddress": "169.254.200.12", "sessionId": null, "tokenValue": "b34841b4-61fa-4dbb-9e2b-76496deb27b4", "tokenType": "Bearer", "decodedDetails": null }, "authenticated": true, "userAuthentication": { "authorities": [ { "authority": "ROLE_admin" }, { "authority": "admin" } ], ...Copy the code

Here is a simple test, directly write the interface to return the current user permissions, found permissions are “ROLE_admin, “admin”.