Jelajahi Sumber

sa-token 校验

chejianzheng 3 bulan lalu
induk
melakukan
cd066dd904

+ 23 - 0
pom.xml

@@ -137,6 +137,29 @@
             <artifactId>knife4j-openapi3-ui</artifactId>
             <version>4.1.0</version>
         </dependency>
+
+        <!-- Sa-Token 权限认证(Reactor响应式集成), 在线文档:https://sa-token.cc -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-reactor-spring-boot-starter</artifactId>
+            <version>1.44.0</version>
+        </dependency>
+
+        <!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-redis-jackson</artifactId>
+            <version>1.44.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <!-- SpringBoot Boot Redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 3 - 2
src/main/java/cn/hfln/framework/gateway/GatewayApplication.java

@@ -6,8 +6,9 @@ import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 @SpringBootApplication(
-    scanBasePackages = {"cn.hfln.framework.gateway"},
-    exclude = {RedisAutoConfiguration.class}
+    scanBasePackages = {"cn.hfln.framework.gateway"}
+//        , exclude = {RedisAutoConfiguration.class
+//    }
 )
 @EnableDiscoveryClient
 public class GatewayApplication {

+ 41 - 0
src/main/java/cn/hfln/framework/gateway/componet/GatewayLogFilter.java

@@ -0,0 +1,41 @@
+package cn.hfln.framework.gateway.componet;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+@Component
+@Slf4j
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class GatewayLogFilter implements GlobalFilter, Ordered {
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        
+        // 打印请求日志(转发前)
+        log.info("[Gateway] Request => Method: {}, Path: {}, Headers: {}, QueryParams: {}", 
+                request.getMethod(), 
+                request.getPath(), 
+                request.getHeaders(),
+                request.getQueryParams());
+
+        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
+            // 打印响应日志(转发后)
+            log.info("[Gateway] Response => Status: {}, Headers: {}",
+                    exchange.getResponse().getStatusCode(),
+                    exchange.getResponse().getHeaders());
+        }));
+    }
+
+    @Override
+    public int getOrder() {
+        return Ordered.HIGHEST_PRECEDENCE; // 优先级最高
+    }
+}

+ 44 - 0
src/main/java/cn/hfln/framework/gateway/config/FastJson2JsonRedisSerializer.java

@@ -0,0 +1,44 @@
+package cn.hfln.framework.gateway.config;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.JSONWriter;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.nio.charset.Charset;
+
+/**
+ * Redis使用FastJson序列化
+ *
+ * @author cw
+ */
+public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
+    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+
+    private Class<T> clazz;
+
+
+    public FastJson2JsonRedisSerializer(Class<T> clazz) {
+        super();
+        this.clazz = clazz;
+    }
+
+    @Override
+    public byte[] serialize(T t) throws SerializationException {
+        if (t == null) {
+            return new byte[0];
+        }
+        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
+    }
+
+    @Override
+    public T deserialize(byte[] bytes) throws SerializationException {
+        if (bytes == null || bytes.length <= 0) {
+            return null;
+        }
+        String str = new String(bytes, DEFAULT_CHARSET);
+
+        return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
+    }
+}

+ 20 - 20
src/main/java/cn/hfln/framework/gateway/config/IgnoreUrlsConfig.java

@@ -1,20 +1,20 @@
-package cn.hfln.framework.gateway.config;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-/**
- * @USER: YangLiu
- * 网关白名单配置
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@Component
-@ConfigurationProperties(prefix="secure.ignore")
-public class IgnoreUrlsConfig {
-    private List<String> urls;
-}
+//package cn.hfln.framework.gateway.config;
+//
+//import lombok.Data;
+//import lombok.EqualsAndHashCode;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.List;
+//
+///**
+// * @USER: YangLiu
+// * 网关白名单配置
+// */
+//@Data
+//@EqualsAndHashCode(callSuper = false)
+//@Component
+//@ConfigurationProperties(prefix="secure.ignore")
+//public class IgnoreUrlsConfig {
+//    private List<String> urls;
+//}

+ 58 - 0
src/main/java/cn/hfln/framework/gateway/config/RedisConfig.java

@@ -0,0 +1,58 @@
+package cn.hfln.framework.gateway.config;
+
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * redis配置
+ *
+ * @author cw
+ */
+@Configuration
+@EnableCaching
+//@AutoConfigureBefore(RedisAutoConfiguration.class)
+public class RedisConfig extends CachingConfigurerSupport {
+
+
+    @Bean
+    @SuppressWarnings(value = {"unchecked", "rawtypes"})
+    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+        template.setValueSerializer(serializer);
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(serializer);
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
+    @Bean
+    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory) {
+        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
+
+        container.setConnectionFactory(factory);
+
+        //  container.setTaskExecutor(null);            // 设置用于执行监听器方法的 Executor
+        //  container.setErrorHandler(null);            // 设置监听器方法执行过程中出现异常的处理器
+        //  container.addMessageListener(null, null);   // 手动设置监听器 & 监听的 topic 表达式
+        return container;
+    }
+}

+ 355 - 0
src/main/java/cn/hfln/framework/gateway/config/RedisService.java

@@ -0,0 +1,355 @@
+package cn.hfln.framework.gateway.config;
+
+import cn.hutool.core.util.RandomUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ *
+ * @author cw
+ **/
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+@Component
+public class RedisService implements CommandLineRunner {
+    @Autowired
+    public RedisTemplate redisTemplate;
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key   缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value) {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 分布式锁
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean setNx(final String key, String value) {
+        return redisTemplate.opsForValue().setIfAbsent(key, value);
+    }
+
+    /**
+     * 分布式锁
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean setNx(final String key, String value, final Long timeout, final TimeUnit timeUnit) {
+        return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key      缓存的键值
+     * @param value    缓存的值
+     * @param timeout  时间
+     * @param timeUnit 时间颗粒度
+     */
+    public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout)
+    {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @param unit 时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit)
+    {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 获取有效时间
+     *
+     * @param key Redis键
+     * @return 有效时间
+     */
+    public long getExpire(final String key)
+    {
+        return redisTemplate.getExpire(key);
+    }
+
+    /**
+     * 判断 key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public Boolean hasKey(String key)
+    {
+        return redisTemplate.hasKey(key);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getCacheObject(final String key)
+    {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public Long increment(final String key) {
+        return redisTemplate.opsForValue().increment(key);
+    }
+
+    public Long incrementMap(String key, String filed) {
+        return redisTemplate.opsForHash().increment(key, filed, 1L);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     * @param key
+     */
+    public boolean deleteObject(final String key) {
+        return redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     * @return
+     */
+    public boolean deleteObject(final Collection collection)
+    {
+        return redisTemplate.delete(collection) > 0;
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key 缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList)
+    {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> keys(final String pattern)
+    {
+        return redisTemplate.keys(pattern);
+    }
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key)
+    {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key 缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
+    {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext())
+        {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key)
+    {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 添加元素缓存的set
+     * @param key
+     * @param values
+     * @return
+     * @param <T>
+     */
+    public <T> Long addCacheSet(final String key, final T... values)
+    {
+        return redisTemplate.opsForSet().add(key, values);
+    }
+
+    /**
+     * 删除缓存set的元素
+     * @param key
+     * @param values
+     * @return
+     * @param <T>
+     */
+    public <T> Long removeCacheSet(final String key, final T... values)
+    {
+        return redisTemplate.opsForSet().remove(key, values);
+    }
+
+    /**
+     * 缓存的set的size
+     * @param key
+     * @return
+     * @param <T>
+     */
+    public <T> Long size(final String key)
+    {
+        return redisTemplate.opsForSet().size(key);
+    }
+
+    /**
+     * set是否包含value
+     * @param key
+     * @param object
+     * @return
+     */
+    public Boolean isMember(final String key, final Object object)
+    {
+        return redisTemplate.opsForSet().isMember(key, object);
+    }
+
+    /**
+     * 缓存Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
+    {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key)
+    {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
+    {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey)
+    {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
+    {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 删除Hash中的某条数据
+     *
+     * @param key  Redis键
+     * @param hKey Hash键
+     * @return 是否成功
+     */
+    public boolean deleteCacheMapValue(final String key, final String hKey) {
+        return redisTemplate.opsForHash().delete(key, hKey) > 0;
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        redisTemplate.opsForValue().set("test", RandomUtil.randomString(2));
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+}

+ 19 - 0
src/main/java/cn/hfln/framework/gateway/config/SaTokenConfigProperties.java

@@ -0,0 +1,19 @@
+package cn.hfln.framework.gateway.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "sa-token.config")
+public class SaTokenConfigProperties {
+
+    private List<String> ignoreUrls;
+
+    private List<String> loginUrls;
+
+    private String portalServiceName;
+}

+ 57 - 0
src/main/java/cn/hfln/framework/gateway/config/SaTokenConfigure.java

@@ -0,0 +1,57 @@
+package cn.hfln.framework.gateway.config;
+
+import cn.dev33.satoken.reactor.filter.SaReactorFilter;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * [Sa-Token 权限认证] 配置类
+ * @author click33
+ */
+@Configuration
+public class SaTokenConfigure {
+
+	@Autowired
+	private SaTokenConfigProperties saTokenConfigProperties;
+	// 注册 Sa-Token全局过滤器
+	@Bean
+	public SaReactorFilter getSaReactorFilter() {
+		return new SaReactorFilter()
+				// 拦截地址
+				.addInclude("/**")    /* 拦截全部path */
+				// 开放地址
+				.setExcludeList(saTokenConfigProperties.getIgnoreUrls())
+				// 鉴权方法:每次访问进入
+				.setAuth(obj -> {
+					// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
+//					SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());
+					SaRouter.match("/**")
+							.notMatch(saTokenConfigProperties.getLoginUrls())
+							.check(r -> StpUtil.checkLogin());
+
+					SaRouter.match(saTokenConfigProperties.getPortalServiceName()+"/**")
+							.notMatch(saTokenConfigProperties.getLoginUrls())
+							.free(rs -> {
+								SaRouter.match(saTokenConfigProperties.getPortalServiceName()+"/admin/**", r -> StpUtil.checkRole("manager"));
+							});
+
+//					// 权限认证 -- 不同模块, 校验不同权限
+//					SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
+//					SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+//					SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+//					SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+
+					// 更多匹配 ...  */
+				})
+				// 异常处理方法:每次setAuth函数出现异常时进入
+				.setError(e -> {
+					return SaResult.error(e.getMessage());
+				})
+				;
+	}
+}
+

+ 69 - 0
src/main/java/cn/hfln/framework/gateway/config/StpInterfaceImpl.java

@@ -0,0 +1,69 @@
+package cn.hfln.framework.gateway.config;
+
+import cn.dev33.satoken.stp.StpInterface;
+
+import cn.dev33.satoken.stp.StpUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码
+ *
+ * @author click33
+ * @since 2022-10-13
+ */
+@Slf4j
+@Component    // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
+public class StpInterfaceImpl implements StpInterface {
+
+
+	@Autowired
+	private RedisService redisService;
+	/**
+	 * 返回一个账号所拥有的权限码集合
+	 */
+	@Override
+	public List<String> getPermissionList(Object loginIdObj, String loginType) {
+
+		List<String> list = new ArrayList<String>();
+		// 后期接口调用次数大的话,可以放redis ,再加更新操作
+		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+
+		List<String> roleList = this.getRoleList(loginId, loginType);
+		for (String roleId : roleList) {
+			String rolePermKeyPre = "hfln:perm:";
+			Set<String> permList = redisService.getCacheSet(rolePermKeyPre + roleId);
+			if (permList == null) {
+				log.error("角色权限列表不存在, roleId :{}", roleId);
+				throw new RuntimeException(roleId + "角色权限列表不存在");
+			}
+			list.addAll(permList);
+		}
+		return list;
+	}
+
+	/**
+	 * 返回一个账号所拥有的角色标识集合
+	 */
+	@Override
+	public List<String> getRoleList(Object loginIdObj, String loginType) {
+
+		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+		// 当前登录用户的角色
+		String roleKeyPre = "hfln:role:";
+		Set<String> roleList = redisService.getCacheSet(roleKeyPre + loginId);
+		if (CollectionUtils.isEmpty(roleList)) {
+			log.error("角色配置异常, loginId :{}", loginId);
+			throw new RuntimeException("角色配置异常");
+		}
+		return new ArrayList<>(roleList);
+	}
+
+}

+ 11 - 1
src/main/resources/application-local.yml

@@ -18,7 +18,7 @@ spring:
     # 数据库索引
     database: 5
     # 密码
-    password: Hfln@1024
+#    password: Hfln@1024
     # 连接超时时间
     timeout: 10s
     lettuce:
@@ -33,3 +33,13 @@ spring:
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
 
+logging:
+  level:
+    cn.dev33.satoken: DEBUG
+
+
+sa-token:
+  # token 名称(同时也是 cookie 名称)
+  token-name: token
+  # 是否输出操作日志
+  is-log: true

+ 21 - 20
src/main/resources/application.yml

@@ -2,7 +2,7 @@ server:
   port: 8090
 spring:
   profiles:
-    active: test
+    active: local
   application:
     name: hfln-interior-gateway
   cloud:
@@ -42,22 +42,23 @@ springdoc:
       paths-to-match: /portal-service-server/**
       packages-to-scan: cn.hfln
 
-# 安全配置
-secure:
-  ignore:
-    urls:
-      - "/doc.html"
-      - "/swagger-resources/**"
-      - "/swagger/**"
-      - "/v3/api-docs/**"
-      - "/**/v2/api-docs"
-      - "/**/*.js"
-      - "/**/*.css"
-      - "/**/*.png"
-      - "/**/*.ico"
-      - "/webjars/**"
-      - "/actuator/**"
-      - "/auth/oauth/token"
-      - "/auth/oauth/check_token"
-      - "/auth/oauth/token_key"
-      - "/auth/rsa/publicKey"
+
+sa-token:
+  config:
+    portalServiceName: /portal-service-server
+    ignoreUrls:
+      - /wap/user/**
+      - /v2/**
+      - /doc.html
+      - /swagger-resources/**
+      - /webjars/**
+      - /swagger-ui/**
+      - /swagger-ui.html
+      - /v3/**
+      - /*/v3/**
+      - /api-docs/**
+      - /api/doc.html
+      - /knife4j/**
+    loginUrls:
+      - /portal-service-server/admin/manage/login
+      - /portal-service-server/wap/user/wx/loginByPhone