Small Hub read:

Explain video also synchronous release, remember to see ha, one button three link wow.

Video tutorial: www.bilibili.com/video/bv1SD…

This system, must learn the user – service authentication, service – service authentication that set, this is to learn.


Introduction to the

Cloud-platform is the first micro-service development Platform based on Spring Cloud in China. It has a unified authorization and authentication background management system, including multiple modules such as user management, resource rights management and gateway API management. It supports the parallel development of multi-service systems and can serve as the development scaffolding for back-end services. Simple code, clear architecture, suitable for learning and direct project use. The core technology adopts Spring Boot 2.1.2 and Spring Cloud (Greenwich.RELEASE) related core components, Nacos registration and configuration center, integrated flow guard Sentinel, and vue-element-Admin component at the front end. Elastic Search integrates itself.

Video explanation of station B:

Ps: Note that this article is based on cloud-Platform V2.5, not the latest version!

Technology selection

Front end: vue – element – admin

Backend: SpringCloud (Eureka, Gateway, Admin, Sidecar, Hystrix, Feign, Ribbon, Zipkin), TK + Mybatis, Lucene, JWT, rest

The project structure

Ace ws-security ace - modules -- -- -- -- -- -- -- -- -- -- -- -- -- -- the public service module based system, search, (OSS) ace - auth -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- service authentication center Ace - gate -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ace - common gateway load center -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- general scaffolding ace - control -- -- -- -- -- -- -- -- -- -- -- -- -- -- operations center (monitoring, link) Ace-sidebar -------------- Invokes third-party language servicesCopy the code

Project start

Note: Cloud-platform is a project separated from the front and back ends. Therefore, the back-end services must be started first. After the back-end services are started, the front-end projects can be started.

The environment

  • Mysql, Redis, Maven
  • jdk1.8
  • IDE plug-in, lombok plug-in, specific Baidu can be
  • node

The front end

Git link: gitee.com/geek_qi/clo…

  • Clone to the local computer and go to cloud-platform-UI to open the command-line window (CMD).
  • Because node.js is involved, you need to install NPM, Node, etc

Node.js installation tutorial: nodejs.cn/download/ download the MSI version and install it.

If the cli is displayed, the installation is successful.

Package dependencies for the project

# 1, installation taobao mirror rely on NPM install - g CNPM - registry=https://registry.npm.taobao.org # 2, install project depend on CNPM NPM install # start service run devCopy the code

After successful startup, the link http://localhost:9527/ will be automatically opened

The back-end

First clone project down (v2.5) : gitee.com/geek_qi/clo…

SQL > select * from db;

Alter database account password (CTRL + SHIRT + R, search datasource:)

Next, start Redis, and then start our services in installation sequence

CenterBootstrap -> AuthBootstrap -> AdminBootstrap -> GatewayServerBootstrapCopy the code

Other monitoring or services may not be started.

Service description

ace-auth-server

Key categories:

  • AuthController

    • For controllers that start with/JWT, log in, refresh, and verify JWT
    • The gateway does not block the request for this link
  • ClientController

    • You can obtain the resources related to authorization based on the ID and key of the exposed interface
  • ServiceController

    • Background management system service management module interface
  • ClientTokenInterceptor

    • Intercepts feIGN interface requests and automatically adds request header tokens
  • ServiceAuthRestInterceptor

    • The intercepted URL is /service/** (WebConfiguration)
    • Invocation authentication between services
    • It is called in feign or restTemplate mode
  • UserAuthRestInterceptor

    • The intercepted URL is /service/** (WebConfiguration)
    • Get user’s token and parse, add user information to session context (ThreadLocal)
  • OkHttpTokenInterceptor

    • Intercept all feign requests and OkHttp rewrite requests
    • OkHttp3 is a powerful mechanism to monitor, rewrite, and retry calls

Module analysis

The user authorization

First of all, let’s make clear the login process, what happened during and after login, so we open the front login page, press F12, and then click Login, you can see the following actions:

  • Click login, and submit the form: http://localhost:9527/api/auth/jwt/token
# the return value {"status":200,"data":"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInVzZXJJZCI6IjEiLCJuYW1lIjoiTXIuQUciLCJleHAiOjE1NjE0NDEyN TZ9.tXNw8nhAFmI4QIQDpKy4DzWtJSTpfwD4685JqbA2pGScdyfXt_5DDs_r1gVZA4CwQC4oZxBsmLKZGclTLGc4HKeXlP2PiVoHZfSWymFRLNfvFqOzKUET J6WpyDqK55yjf1wddTBD3VzSFvY49uunvozEcb2oFjOs3M_I2sgxAAU","rel":false}Copy the code

After successful login, a JWT token value is returned, which should be the token used to identify the user’s identity.

  • Ajax requests for user information and the menu list: http://localhost:9527/api/admin/user/front/info? token=eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInVzZXJJZCI6IjEiLCJuYW1lIjoiTXIuQUciLCJleHAiOjE1NjE0NDEyNTZ9.tXNw8nhAFmI4 QIQDpKy4DzWtJSTpfwD4685JqbA2pGScdyfXt_5DDs_r1gVZA4CwQC4oZxBsmLKZGclTLGc4HKeXlP2PiVoHZfSWymFRLNfvFqOzKUETJ6WpyDqK55yjf1wd dTBD3VzSFvY49uunvozEcb2oFjOs3M_I2sgxAAU
# the return value {"id":"1","username":"admin","name":"Mr.AG","description":"","menus":[{"code":"userManager","type":"menu","uri":"/admin/ User ", "method" : "GET", "name" : "access", "menu" : "user management"}, {" code ":" baseManager ", "type" : "menu", "uri" : "/ admin", "method" : "GET", "name" :" Access ","menu":" basic configuration management "}, ... (the deleted part), {" code ":" serviceManager: btn_clientManager ", "type" : "button", "uri" : "/ auth/service / {*} / client", "method" : "POS T","name":" service authorization ","menu":" service management "}]}Copy the code

Also notice the information in the request header: it contains the JWT token that was logged in earlier, and the name is Authorization. All subsequent requests will carry this Authorization to identify the user.

Let’s go through the process:

  • The client click on the button to launch the login request at http://localhost:9527/api/auth/jwt/token

    • The gateway gate is first reached through our AccessGatewayFilter
      • Gets the request URI, method
      • Check whether the address is not intercepted
      • Gate: ignore: startWith: /auth/ JWT
      • So the gateway filter proxies requests directly to the ACE-Auth service
  • Gateway Ace-gateway-v2 proxy and filtering configuration

Rule # gateway proxy spring: cloud: gateway: a locator: enabled: true routes: # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = - id: ace-auth uri: lb://ace-auth order: 8000 predicates: - Path=/api/auth/** filters: - StripPrefix=2 - id: ace-admin uri: lb://ace-admin order: 8001 predicates: - Path=/api/admin/** filters: - StripPrefix=2 gate: ignore: startWith: /auth/jwtCopy the code

So let’s go into ace-Auth and find the corresponding controller, which we can find here:

@RestController
@RequestMapping("jwt")
@Slf4j
public class AuthController {    @RequestMapping(value = "token", method = RequestMethod.POST)
    public ObjectRestResponse<String> createAuthenticationToken(
            @RequestBody JwtAuthenticationRequest authenticationRequest) throws Exception {
        log.info(authenticationRequest.getUsername()+" require logging...");
        final String token = authService.login(authenticationRequest);
        return new ObjectRestResponse<>().data(token);
    }
}
Copy the code

The only method in this method is authService.login, and when I click on this method, I find another method in this method called UserService. validate, which is an feign interface

@FeignClient(value = "ace-admin",configuration = FeignConfiguration.class)
public interface IUserService {  @RequestMapping(value = "/api/user/validate", method = RequestMethod.POST)
  public UserInfo validate(@RequestBody JwtAuthenticationRequest authenticationRequest);
Copy the code

}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

Inter-service authentication

The class above, userService.validate, has this annotation

@feignClient (value = "ace-admin",configuration = feignConfiguration. class) indicates that the ace-admin service is invoked declaratively. We can see that there is a configuration = feignConfiguration. class, We open FeignConfiguration @Configuration Public class FeignConfiguration {@bean ClientTokenInterceptor getClientTokenInterceptor(){ return new ClientTokenInterceptor(); }}Copy the code

Open ClientTokenInterceptor again:

public class ClientTokenInterceptor implements RequestInterceptor { private Logger logger = LoggerFactory.getLogger(ClientTokenInterceptor.class); @Autowired private ClientConfiguration clientConfiguration; @Autowired private AuthClientService authClientService; @override public void apply(RequestTemplate RequestTemplate) {logger.info("----> add token header for feign call "); try { requestTemplate.header(clientConfiguration.getClientTokenHeader(), authClientService.apply(clientConfiguration.getClientId(), clientConfiguration.getClientSecret())); } catch (Exception e) { e.printStackTrace(); RequestInterceptor is an interceptor that adds a request header to a feIGN request when it makes a remote call. Therefore, the request header has the identity token of the current service, and the receiving server can identify the source server based on the token.Copy the code

Now let’s see how the receiver can tell. ServiceAuthRestInterceptor

public class ServiceAuthRestInterceptor extends HandlerInterceptorAdapter { private Logger logger = LoggerFactory.getLogger(ServiceAuthRestInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object Handler) throws Exception {logger.info("------> Check whether service A has permission to access service B ~"); HandlerMethod handlerMethod = (HandlerMethod) handler; / / configure the annotations, not for service intercept IgnoreClientToken annotation = handlerMethod. GetBeanType (). The getAnnotation (IgnoreClientToken. Class); if (annotation == null) { annotation = handlerMethod.getMethodAnnotation(IgnoreClientToken.class); } if(annotation! =null) { return super.preHandle(request, response, handler); } String token = request.getHeader(serviceAuthConfig.getTokenHeader()); IJWTInfo infoFromToken = serviceAuthUtil.getInfoFromToken(token); String uniqueName = infoFromToken.getUniqueName(); For (String client: serviceAuthUtil getAllowedClient ()) {/ / ace - auth, ace - gate the if (client) equals (uniqueName)) {return super.preHandle(request, response, handler); } } throw new ClientForbiddenException("Client is Forbidden!" ); }}Copy the code

Look at the code first to see if there are any IgnoreClientToken annotations, and skip them if there are. If not continue to get calls token of backend server, and then to obtain the current server allows access to lient (serviceAuthUtil. GetAllowedClient ()), and call the matching name is within the allowed the client, if allowed to continue, Forbidden. So it’s pretty clear. So where is this relationship between clients and clients that are allowed to access maintained, there are actually two tables

  • Auth_client: indicates the ID and name of the client
  • Auth_client_service: client association table that the server is allowed to call

From this table, we can figure out what is allowed and what is not

Cloud-platform Authentication logic. PNG

Optimization of inter-service invocation. PNG

conclusion

The first thing to do

  • Create all needed modules and basically build the framework
  • Add, delete, change and check the packaging, interface specifications
  • Global exception capture encapsulation
  • Unit testing
  • General utility class

The second thing

  • Determine the authorization mode of the service (JWT, OAUTH2, etc.)

The third thing

  • Service internal authentication
  • Access control

(after)

Video tutorial: www.bilibili.com/video/bv1SD…