本文承接上文《从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的登陆地址变为了如下地址,请求时也只需要输入账号密码