当前位置:网站首页>Unified certification center oauth2 certification pit

Unified certification center oauth2 certification pit

2022-06-10 15:37:00 InfoQ

In the previous article  
Springcloud Oauth2 HA piece
  in , Based on  Oauth2  Unified authentication and authorization . In the configuration , We can see :

cas-server-url: http://cas-server-service # The configuration here is HA Address

security:
 oauth2: # And cas-server Corresponding configuration
 client:
 client-id: admin-web
 client-secret: admin-web-123
 user-authorization-uri: ${cas-server-url}/oauth/authorize # It is required by the authorization code authentication method
 access-token-uri: ${cas-server-url}/oauth/token # It's the access required by password mode  token  The interface of
 resource:
 loadBalanced: true
 id: admin-web
 user-info-uri: ${cas-server-url}/api/user # Appoint user info Of URI
 prefer-token-info: false

there  url  Configuration is based on k8s Of  Service, Load balancing , To achieve high availability . But let's analyze  user-info-uri.user-info-uri  The principle of is to send the authentication information after the authorization server authenticates  Principal  The method of binding through formal parameters URL To get user information . Of course, it also has supporting  UserInfoTokenService  etc. .

But when the client obtains user permission , There are some problems . for example  Web The client requests an interface of the consumer :

/**
 *  Return all discovered Services
 * @author Damon
 * @date 2021 year 11 month 2 Japan   Afternoon 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 = &quot;&quot;;
 try {
 ResponseEntity<String> responseEntity = restTemplate.exchange(&quot;http://cas-server/api/v1/user&quot;,
 HttpMethod.GET, formEntity, String.class);
 if (responseEntity.getStatusCodeValue() == 200) {
 return &quot;ok&quot;;
 }
 } catch (Exception e) {
 System.out.println(e.getMessage());
 }
 return body;
 }

In this interface , We add
@PreAuthorize(&quot;hasRole('admin')&quot;)
To control authority , As long as it is admin Users can access the interface .

Let's first request the login interface of the Certification Center , obtain token:

null
Get the token after , We request this interface , We will find that :

null
Description not certified , Let's see : It turns out that when this interface is requested , The consumer then requests the interface of the authentication center :

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]
2021-11-03 15:59:09.427 DEBUG 127896 --- [io2-2001-exec-4] org.springframework.web.HttpLogging : Response 404 NOT_FOUND
2021-11-03 15:59:09.446 DEBUG 127896 --- [io2-2001-exec-4] o.s.w.c.HttpMessageConverterExtractor : Reading to [org.springframework.security.oauth2.common.exceptions.OAuth2Exception]
2021-11-03 15:59:09.456 WARN 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 : [{&quot;timestamp&quot;:&quot;2021-11-03T07:59:09.423+00:00&quot;,&quot;status&quot;:404,&quot;error&quot;:&quot;Not Found&quot;,&quot;message&quot;:&quot;&quot;,&quot;path&quot;:&quot;/auth/user&quot;}]
2021-11-03 15:59:09.457 ERROR 127896 --- [io2-2001-exec-4] c.l.h.CustomAuthenticationEntryPoint :  invalid token, Please re authenticate to visit
{&quot;data&quot;:&quot;b34841b4-61fa-4dbb-9e2b-76496deb27b4&quot;,&quot;result&quot;:{&quot;code&quot;:20202,&quot;msg&quot;:&quot; Uncertified &quot;,&quot;status&quot;:401}}

But the certification center returned
404
Status code , At this time, the unified exception EntryPoint Prompt error :
invalid token, Please re authenticate to visit
. So as to return the information body :
{&quot;data&quot;:&quot;b34841b4-61fa-4dbb-9e2b-76496deb27b4&quot;,&quot;result&quot;:{&quot;code&quot;:20202,&quot;msg&quot;:&quot; Uncertified &quot;,&quot;status&quot;:401}}
.

The next analysis : Why does the certification authority return
404
Well ? Look at the certification center log :

2021-11-03 15:59:09.407 DEBUG 54492 --- [o2-2000-exec-15] o.s.web.servlet.DispatcherServlet : GET &quot;/auth/user&quot;, parameters={}
2021-11-03 15:59:09.409 DEBUG 54492 --- [o2-2000-exec-15] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [&quot;classpath:/META-INF/resources/&quot;, &quot;classpath:/resources/&quot;, &quot;classpath:/static/&quot;, &quot;classpath:/public/&quot;]
2021-11-03 15:59:09.413 DEBUG 54492 --- [o2-2000-exec-15] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2021-11-03 15:59:09.414 DEBUG 54492 --- [o2-2000-exec-15] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2021-11-03 15:59:09.422 DEBUG 54492 --- [o2-2000-exec-15] o.s.web.servlet.DispatcherServlet : &quot;ERROR&quot; dispatch for GET &quot;/error&quot;, parameters={}
2021-11-03 15:59:09.423 DEBUG 54492 --- [o2-2000-exec-15] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2021-11-03 15:59:09.424 DEBUG 54492 --- [o2-2000-exec-15] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json] and supported [application/json, application/*+json, application/json, application/*+json, application/json, application/*+json]
2021-11-03 15:59:09.424 DEBUG 54492 --- [o2-2000-exec-15] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Wed Nov 03 15:59:09 CST 2021, status=404, error=Not Found, message=, path=/auth/user}]
2021-11-03 15:59:09.426 DEBUG 54492 --- [o2-2000-exec-15] o.s.web.servlet.DispatcherServlet : Exiting from &quot;ERROR&quot; dispatch, status 404

Discover the original Oauth2 There is no such interface :
/auth/user
. Finally, I decided to write an interface to replace the native interface :

@GetMapping(&quot;/api/v1/user&quot;)
 public Authentication user(Map map, Principal user, Authentication auth) {
 // Get current user information
 logger.info(&quot;cas-server provide user: &quot; + JSON.toJSONString(auth));
 return auth;
 }

In the packaging 、 After coverage , Directly configure relevant configurations 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

Start the Certification Center at the same time 、 The consumer end , Keep getting token after , Request interface :

null
here , Found to be
403
, I don't have permission , Now we can add this permission to the user :

&quot;authorities&quot;: [ { &quot;authority&quot;: &quot;ROLE_admin&quot; }, { &quot;authority&quot;: &quot;admin&quot; }

And then when we're done , We found that the request interface can be successful :

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

Here's a simple test , Directly write the interface that returns the current user's permission , Discovery permissions are &quot;ROLE_admin、&quot;admin&quot;.

summary

Sometimes the official website has very little source code analysis , We must look at the source code , Only by combining with practical actions can we accurately analyze its intention . So when it doesn't exist 、 Or when our needs are not met , You can choose to override its source logic , Implement custom mode , This will avoid a lot of unnecessary trouble . Because the source code analysis is different , The corresponding source code is also different .
原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206101524485885.html