本文承接上文《从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(八) (mini-cloud) saas平台篇-解决不同租户针定制化开发问题 -完整代码以及案例方案(1)》
为什么要挂载用户自定义登陆端以及自定义业务端,上节已经说过一些原因,这节补充下,主要原因有以下几点:
1。屏蔽登陆得clientid 以及clientSecret,因为多租户情况下需要client信息才可以确认租户信息
2.自定义登陆封装个性化信息,不同租户也许需要登陆后外围包装一些自己业务端的业务信息
3.租户自己需要重写或者新增某些功能,自己的业务端与自定义前端联通开发自己一套微服务应用
如何自定义租户自定义登陆断和业务端
原登陆需要指定框架共通的登陆url,并且输入clientid,clientSecret和grantType ,如下图
用户自定义部分模型如下
创建一个租户id是1的租户项目,创建一个登陆部分的子工程,代码结构如下
nacos 新增mini-cloud-busi-tanent-1-login-dev.yml文件
代码明细,正常添加controller 层,service层 ,只不过登陆变为了这个工程代理访问原url
TanentLoginController.java
package com.minicloud.busi.login.controller; import com.minicloud.busi.login.service.TanentLoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Optional; @RestController @RequestMapping("/tanent") public class TanentLoginController { @Autowired private TanentLoginService tanentLoginService; @PostMapping("/login") public ResponseEntity tanentLogin(@RequestParam("username") String username, @RequestParam("password") String password) throws Exception { return ResponseEntity.of(Optional.of(tanentLoginService.login(username, password))); } }
TanentLoginServiceImpl.java
@Service public class TanentLoginServiceImpl implements TanentLoginService { @Autowired private DiscoveryClient discoveryClient; @Value("${tanent.login.scope}") private String scope; @Value("${tanent.login.grant_type}") private String grantType; @Value("${tanent.login.client_id}") private String clientId; @Value("${tanent.login.client_secret}") private String clientSecret; @Override public String login(String username, String password) throws Exception { List<ServiceInstance> serviceInstances = discoveryClient.getInstances("mini-cloud-authentication-center"); for(ServiceInstance serviceInstance:serviceInstances){ String response = login(username,password,serviceInstance); if(null != response){ return response; } } throw new Exception("null auth instance could be used"); } private String login(String username, String password, ServiceInstance serviceInstance) { try { String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/oauth/token"; Map map = MapUtil.builder(). put("username",username). put("password",password). put("scope",scope). put("grant_type",grantType). put("client_id",clientId). put("client_secret",clientSecret).build(); HttpRequest httpRequest = HttpRequest.post(url).form(map); return httpRequest.execute().body(); }catch (Exception e){ e.printStackTrace(); } return null; } }
重点是这里,目的是转交请求到框架的认证中心/auth/oauth/token
第一个红框是为了从注册中心获取可用的认证中心实例
bootstrap-dev.yml
server: port: 7500 tomcat: uri-encoding: UTF-8 threads: max: 500 max-connections: 10240 accept-count: 500 spring: application: name: @artifactId@ cloud: nacos: discovery: server-addr: ${NACOS_HOST:mini-cloud-resiger}:${NACOS_PORT:8848} metadata: version: wl config: server-addr: ${spring.cloud.nacos.discovery.server-addr} file-extension: yml shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} profiles: active: @profiles.active@
集成完毕,启动,查看服务实例
现在租户1的用户登陆变成了如下登陆方式,租户1的登陆地址变为了如下地址,请求时也只需要输入账号密码