feat: 对接POA的用户服务、授权服务完成用户登录
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/Role.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/Role.java
new file mode 100644
index 0000000..f8bd6e7
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/Role.java
@@ -0,0 +1,41 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.model;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@ToString
+public class Role implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -273297347381636597L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private String code;
+
+ @Getter
+ @Setter
+ private String name;
+
+ @Getter
+ @Setter
+ private String description;
+
+ @Getter
+ @Setter
+ private Boolean enabled;
+
+ @Getter
+ @Setter
+ private String externalId;
+
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/UserInfoModel.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/UserInfoModel.java
new file mode 100644
index 0000000..f9c23af
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/model/UserInfoModel.java
@@ -0,0 +1,124 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.model;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@ToString
+public class UserInfoModel implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -822608981040243176L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private String accountName;
+
+ @Getter
+ @Setter
+ private String identityTypeId;
+ @Getter
+ @Setter
+ private String identityTypeCode;
+ @Getter
+ @Setter
+ private String identityTypeName;
+
+ @Getter
+ @Setter
+ private String organizationId;
+ @Getter
+ @Setter
+ private String organizationCode;
+ @Getter
+ @Setter
+ private String organizationName;
+
+ @Getter
+ @Setter
+ private String uid;
+
+ @Getter
+ @Setter
+ private String name;
+
+ @Getter
+ @Setter
+ private String fullNameSpelling;
+ @Getter
+ @Setter
+ private String nameSpelling;
+
+ @Getter
+ @Setter
+ private String certificateTypeId;
+ @Getter
+ @Setter
+ private String certificateTypeCode;
+ @Getter
+ @Setter
+ private String certificateTypeName;
+ @Getter
+ @Setter
+ private String certificateNumber;
+
+ @Getter
+ @Setter
+ private String genderId;
+ @Getter
+ @Setter
+ private String genderCode;
+ @Getter
+ @Setter
+ private String genderName;
+
+ @Getter
+ @Setter
+ private String nationId;
+ @Getter
+ @Setter
+ private String nationCode;
+ @Getter
+ @Setter
+ private String nationName;
+
+ @Getter
+ @Setter
+ private String countryId;
+ @Getter
+ @Setter
+ private String countryCode;
+ @Getter
+ @Setter
+ private String countryName;
+
+ @Getter
+ @Setter
+ private String addressId;
+ @Getter
+ @Setter
+ private String addressCode;
+ @Getter
+ @Setter
+ private String addressName;
+
+ @Getter
+ @Setter
+ private String phoneNumber;
+ @Getter
+ @Setter
+ private String email;
+
+ @Getter
+ @Setter
+ private String imageUrl;
+
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/configuration/AgentPoaRestTemplateConfig.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/configuration/AgentPoaRestTemplateConfig.java
new file mode 100644
index 0000000..f26b518
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/configuration/AgentPoaRestTemplateConfig.java
@@ -0,0 +1,100 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.remote.configuration;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.SSLContexts;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class AgentPoaRestTemplateConfig {
+
+ @Bean
+ public ClientHttpRequestFactory simpleClientHttpRequestFactory(
+ @Value("${sw-backend-agent-poa.client-auth.enabled:false}") boolean enabled,
+ @Value("${sw-backend-agent-poa.client-auth.key-password:}") String keyPassword,
+ @Value("${sw-backend-agent-poa.client-auth.key-store:}") String keyStore,
+ @Value("${sw-backend-agent-poa.client-auth.key-store-password:}") String keyStorePassword,
+ @Value("${sw-backend-agent-poa.client-auth.trust-store:}") String trustStore,
+ @Value("${sw-backend-agent-poa.client-auth.trust-store-password:}") String trustStorePassword
+ ) {
+ if (!enabled) {
+ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+ factory.setReadTimeout(5000);// 单位为ms
+ factory.setConnectTimeout(5000);// 单位为ms
+ return factory;
+ }
+
+ SSLContextBuilder sslContextBuilder = SSLContexts.custom();
+
+ if (trustStore == null || trustStore.isEmpty()) {
+ } else {
+ try {
+ sslContextBuilder
+ .loadTrustMaterial(
+ ResourceUtils.getFile(trustStore),
+ trustStorePassword.toCharArray()
+ );
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (keyStore == null || keyStore.isEmpty()) {
+ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+ factory.setReadTimeout(5000);// 单位为ms
+ factory.setConnectTimeout(5000);// 单位为ms
+ return factory;
+ } else {
+ try {
+ sslContextBuilder
+ .loadKeyMaterial(
+ ResourceUtils.getFile(keyStore),
+ keyStorePassword.toCharArray(),
+ keyPassword.toCharArray());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ SSLContext sslContext = sslContextBuilder.build();
+
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+ sslContext,
+ SSLConnectionSocketFactory.getDefaultHostnameVerifier());
+
+ CloseableHttpClient httpClient = HttpClients.custom()
+ .setSSLSocketFactory(sslsf)
+ .build();
+
+ HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
+ factory.setReadTimeout(5000);// 单位为ms
+ factory.setConnectTimeout(5000);// 单位为ms
+ return factory;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+ factory.setReadTimeout(5000);// 单位为ms
+ factory.setConnectTimeout(5000);// 单位为ms
+ return factory;
+ }
+
+ @Bean(name = "agentPoaRestTemplate")
+ public RestTemplate agentPoaRestTemplate(ClientHttpRequestFactory requestFactory) {
+ return new RestTemplate(requestFactory);
+ }
+
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/web/client/AgentPoaRemoteClient.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/web/client/AgentPoaRemoteClient.java
new file mode 100644
index 0000000..aaa98bf
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/remote/web/client/AgentPoaRemoteClient.java
@@ -0,0 +1,61 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.remote.web.client;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import com.alibaba.fastjson.JSONObject;
+
+@Slf4j
+@Component
+public class AgentPoaRemoteClient {
+
+ @Autowired
+ private RestTemplate agentPoaRestTemplate;
+
+ @Value(value = "${sw-backend-agent-poa.uri}/v1/poa")
+ private String url;
+
+ private JSONObject defaultErrorJson(Throwable cause) {
+ JSONObject error = new JSONObject();
+
+ error.put("code", -1);
+ error.put("message", cause.getMessage());
+ error.put("error", cause.getMessage());
+
+ return error;
+ }
+
+ public JSONObject loadUserInfoByAccountName(String accountName) {
+ try {
+ final String path = "/user/users/accountName/{accountName}";
+ final String url = this.url + StringUtils.replaceEach(path, new String[] {"{accountName}"}, new String[] {accountName});
+ log.debug(url);
+
+ return agentPoaRestTemplate.getForObject(url, JSONObject.class);
+ } catch (Exception e) {
+ //e.printStackTrace();
+
+ return defaultErrorJson(e);
+ }
+ }
+
+ public JSONObject loadAccountApplicationRoles(String username) {
+ try {
+ final String path = "/authz/roles/account/{username}";
+ final String url = this.url + StringUtils.replaceEach(path, new String[] {"{username}"}, new String[] {username});
+ log.debug(url);
+
+ return agentPoaRestTemplate.getForObject(url, JSONObject.class);
+ } catch (Exception e) {
+ //e.printStackTrace();
+
+ return defaultErrorJson(e);
+ }
+ }
+
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/AuthzService.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/AuthzService.java
new file mode 100644
index 0000000..1d040b6
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/AuthzService.java
@@ -0,0 +1,38 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.service;
+
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.gateway.agent.poa.model.Role;
+import com.supwisdom.institute.backend.gateway.agent.poa.remote.web.client.AgentPoaRemoteClient;
+
+@Slf4j
+@Service
+public class AuthzService {
+
+ @Autowired
+ private AgentPoaRemoteClient agentPoaRemoteClient;
+
+ public List<Role> loadAccountApplicationRoles(String username) {
+
+ JSONObject jsonObject = agentPoaRemoteClient.loadAccountApplicationRoles(username);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ JSONArray roleArray = data.getJSONArray("roles");
+
+ List<Role> roles = roleArray.toJavaList(Role.class);
+ log.debug("{}", roles);
+
+ return roles;
+ }
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/UserService.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/UserService.java
new file mode 100644
index 0000000..777c596
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/agent/poa/service/UserService.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.gateway.agent.poa.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.gateway.agent.poa.model.UserInfoModel;
+import com.supwisdom.institute.backend.gateway.agent.poa.remote.web.client.AgentPoaRemoteClient;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class UserService {
+
+ @Autowired
+ private AgentPoaRemoteClient agentPoaRemoteClient;
+
+ public UserInfoModel loadUserInfoByAccountName(String accountName) {
+
+ JSONObject jsonObject = agentPoaRemoteClient.loadUserInfoByAccountName(accountName);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ UserInfoModel userInfoModel = data.toJavaObject(UserInfoModel.class);
+ log.debug("userInfoModel: [{}]", userInfoModel);
+
+ return userInfoModel;
+ }
+
+}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/configuration/UserDetailsServiceConfig.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/configuration/UserDetailsServiceConfig.java
index 6f8be84..5bc7d6b 100644
--- a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/configuration/UserDetailsServiceConfig.java
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/configuration/UserDetailsServiceConfig.java
@@ -1,10 +1,12 @@
package com.supwisdom.institute.backend.gateway.configuration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.supwisdom.institute.backend.gateway.security.core.userdetails.InMemeryUserDetailsService;
import com.supwisdom.institute.backend.gateway.security.core.userdetails.MyUserDetailsService;
+import com.supwisdom.institute.backend.gateway.security.core.userdetails.PoaUserDetailsService;
import lombok.extern.slf4j.Slf4j;
@@ -13,19 +15,30 @@
public class UserDetailsServiceConfig {
@Bean
- public MyUserDetailsService userDetailsService() throws Exception {
+ @ConditionalOnProperty(name = "sw-backend-gateway.security.core.userdetails.service.impl", havingValue = "memery", matchIfMissing = true)
+ public InMemeryUserDetailsService inMemeryUserDetailsService() throws Exception {
+ InMemeryUserDetailsService inMemeryUserDetailsService = new InMemeryUserDetailsService();
+ log.debug("UserDetailsServiceConfig inMemeryUserDetailsService is {}", inMemeryUserDetailsService);
+
+ return inMemeryUserDetailsService;
+ }
+
+ @Bean
+ @ConditionalOnProperty(name = "sw-backend-gateway.security.core.userdetails.service.impl", havingValue = "poa", matchIfMissing = false)
+ public PoaUserDetailsService poaUserDetailsService() throws Exception {
+ PoaUserDetailsService poaUserDetailsService = new PoaUserDetailsService();
+ log.debug("UserDetailsServiceConfig poaUserDetailsService is {}", poaUserDetailsService);
+
+ return poaUserDetailsService;
+ }
+
+ @Bean
+ @ConditionalOnProperty(name = "sw-backend-gateway.security.core.userdetails.service.impl", havingValue = "base", matchIfMissing = false)
+ public MyUserDetailsService myUserDetailsService() throws Exception {
MyUserDetailsService myUserDetailsService = new MyUserDetailsService();
log.debug("UserDetailsServiceConfig myUserDetailsService is {}", myUserDetailsService);
return myUserDetailsService;
}
-// @Bean
-// public InMemeryUserDetailsService userDetailsService() throws Exception {
-// InMemeryUserDetailsService inMemeryUserDetailsService = new InMemeryUserDetailsService();
-// log.debug("UserDetailsServiceConfig inMemeryUserDetailsService is {}", inMemeryUserDetailsService);
-//
-// return inMemeryUserDetailsService;
-// }
-
}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/PoaUserDetailsService.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/PoaUserDetailsService.java
new file mode 100644
index 0000000..4479be4
--- /dev/null
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/PoaUserDetailsService.java
@@ -0,0 +1,99 @@
+package com.supwisdom.institute.backend.gateway.security.core.userdetails;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import com.supwisdom.institute.backend.gateway.agent.poa.model.Role;
+import com.supwisdom.institute.backend.gateway.agent.poa.model.UserInfoModel;
+import com.supwisdom.institute.backend.gateway.agent.poa.service.AuthzService;
+import com.supwisdom.institute.backend.gateway.agent.poa.service.UserService;
+
+import reactor.core.publisher.Mono;
+
+@Slf4j
+public class PoaUserDetailsService implements UserDetailsService, ReactiveUserDetailsService {
+
+ @Autowired
+ PasswordEncoder passwordEncoder;
+
+ @Autowired
+ UserService userService;
+ @Autowired
+ AuthzService authzService;
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+
+ log.debug("PoaUserDetailsService.loadUserByUsername({})", username);
+
+ MyUser myUser = loadUser(username);
+
+ return myUser;
+ }
+
+ @Override
+ public Mono<UserDetails> findByUsername(String username) {
+
+ log.debug("PoaUserDetailsService.findByUsername({})", username);
+
+ MyUser myUser = loadUser(username);
+
+ return Mono.just(myUser);
+ }
+
+ private MyUser loadUser(String username) {
+
+ UserInfoModel userInfoModel = userService.loadUserInfoByAccountName(username);
+ if (userInfoModel == null) {
+ throw new UsernameNotFoundException(String.format("%s not found", username));
+ }
+
+ List<Role> roles = authzService.loadAccountApplicationRoles(username);
+
+ List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+ for (Role role : roles) {
+ authorities.add(new SimpleGrantedAuthority(role.getCode()));
+ }
+
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put("accountId", userInfoModel.getId());
+ attributes.put("accountName", userInfoModel.getAccountName());
+
+ attributes.put("identityTypeId", userInfoModel.getIdentityTypeId());
+ attributes.put("identityTypeCode", userInfoModel.getIdentityTypeCode());
+ attributes.put("identityTypeName", userInfoModel.getIdentityTypeName());
+
+ attributes.put("organizationId", userInfoModel.getOrganizationId());
+ attributes.put("organizationCode", userInfoModel.getOrganizationCode());
+ attributes.put("organizationName", userInfoModel.getOrganizationName());
+
+ attributes.put("uid", userInfoModel.getUid());
+ attributes.put("name", userInfoModel.getName());
+ attributes.put("genderName", userInfoModel.getGenderName());
+ attributes.put("nationName", userInfoModel.getNationName());
+ attributes.put("countryName", userInfoModel.getCountryName());
+ attributes.put("addressName", userInfoModel.getAddressName());
+
+ attributes.put("imageUrl", userInfoModel.getImageUrl());
+
+ MyUser myUser = new MyUser(userInfoModel.getAccountName(), passwordEncoder.encode(StringUtils.reverse(userInfoModel.getAccountName())),
+ authorities, attributes);
+ log.debug("myUser is {}", myUser);
+
+ return myUser;
+ }
+}
diff --git a/gateway/src/main/resources/application-docker.yml b/gateway/src/main/resources/application-docker.yml
index 661b919..4a25bab 100644
--- a/gateway/src/main/resources/application-docker.yml
+++ b/gateway/src/main/resources/application-docker.yml
@@ -31,7 +31,6 @@
jackson:
time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
-
##
# spring cloud gateway
#
@@ -105,6 +104,14 @@
cas.server.host.url: ${CAS_SERVER_HOST_URL:https://cas-server/cas}
+##
+# 认证时,用户信息服务实现
+# memery 内存,用户名密码一致即可登录,测试用,默认;
+# base 后端base服务;
+# poa 开放平台服务,建议和cas一起使用)
+sw-backend-gateway.security.core.userdetails.service.impl: ${SW_BACKEND_GATEWAY_SECURITY_CORE_USERDETAILS_SERVICE_IMPL:base}
+
+
sw-backend-base-api:
uri: ${SW_BACKEND_BASE_API_URI:https://sw-backend-admin-sa}
client-auth:
@@ -114,4 +121,13 @@
key-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEYSTORE_PASSWORD:}
trust-store: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
trust-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
-
\ No newline at end of file
+
+sw-backend-agent-poa:
+ uri: ${SW_BACKEND_AGENT_POA_URI:https://sw-backend-agent}
+ client-auth:
+ enabled: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_ENABLED:true}
+ key-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEY_PASSWORD:}
+ key-store: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+ key-store-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+ trust-store: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+ trust-store-password: ${SW_BACKEND_AGENT_POA_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
diff --git a/gateway/src/main/resources/application.yml b/gateway/src/main/resources/application.yml
index 1f3be47..2c4fde8 100644
--- a/gateway/src/main/resources/application.yml
+++ b/gateway/src/main/resources/application.yml
@@ -95,5 +95,16 @@
cas.server.host.url: https://cas.supwisdom.com/cas
+##
+# 认证时,用户信息服务实现
+# memery 内存,用户名密码一致即可登录,测试用,默认;
+# base 后端base服务;
+# poa 开放平台服务,建议和cas一起使用)
+sw-backend-gateway.security.core.userdetails.service.impl: memery
+
+
sw-backend-base-api:
uri: http://localhost:8082
+
+sw-backend-agent-poa:
+ uri: http://localhost:8090