Commit deca69ada661636e7a724f77c3c72f745433f722

Authored by YunaiV
1 parent a7e5aaec

【功能优化】AI:DispatcherType.ASYNC 时,不进行认证,解决 Spring AI SSE 的认证问题

https://github.com/YunaiV/yudao-cloud/issues/197
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java
... ... @@ -7,6 +7,7 @@ import com.google.common.collect.HashMultimap;
7 7 import com.google.common.collect.Multimap;
8 8 import jakarta.annotation.Resource;
9 9 import jakarta.annotation.security.PermitAll;
  10 +import jakarta.servlet.DispatcherType;
10 11 import org.springframework.boot.autoconfigure.AutoConfiguration;
11 12 import org.springframework.boot.autoconfigure.AutoConfigureOrder;
12 13 import org.springframework.context.ApplicationContext;
... ... @@ -142,7 +143,9 @@ public class YudaoWebSecurityConfigurerAdapter {
142 143 // ②:每个项目的自定义规则
143 144 .authorizeHttpRequests(c -> authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(c)))
144 145 // ③:兜底规则,必须认证
145   - .authorizeHttpRequests(c -> c.anyRequest().authenticated());
  146 + .authorizeHttpRequests(c -> c
  147 + .dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll() // WebFlux 异步请求,无需认证,目的:SSE 场景
  148 + .anyRequest().authenticated());
146 149  
147 150 // 添加 Token Filter
148 151 httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.java
... ... @@ -20,7 +20,6 @@ import io.swagger.v3.oas.annotations.Operation;
20 20 import io.swagger.v3.oas.annotations.Parameter;
21 21 import io.swagger.v3.oas.annotations.tags.Tag;
22 22 import jakarta.annotation.Resource;
23   -import jakarta.annotation.security.PermitAll;
24 23 import jakarta.validation.Valid;
25 24 import lombok.extern.slf4j.Slf4j;
26 25 import org.springframework.http.MediaType;
... ... @@ -57,7 +56,6 @@ public class AiChatMessageController {
57 56  
58 57 @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快")
59 58 @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
60   - @PermitAll // 解决 SSE 最终响应的时候,会被 Access Denied 拦截的问题
61 59 public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(@Valid @RequestBody AiChatMessageSendReqVO sendReqVO) {
62 60 return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId());
63 61 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/mindmap/AiMindMapController.java
... ... @@ -12,7 +12,6 @@ import io.swagger.v3.oas.annotations.Operation;
12 12 import io.swagger.v3.oas.annotations.Parameter;
13 13 import io.swagger.v3.oas.annotations.tags.Tag;
14 14 import jakarta.annotation.Resource;
15   -import jakarta.annotation.security.PermitAll;
16 15 import jakarta.validation.Valid;
17 16 import org.springframework.http.MediaType;
18 17 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -32,7 +31,6 @@ public class AiMindMapController {
32 31  
33 32 @PostMapping(value = "/generate-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
34 33 @Operation(summary = "导图生成(流式)", description = "流式返回,响应较快")
35   - @PermitAll // 解决 SSE 最终响应的时候,会被 Access Denied 拦截的问题
36 34 public Flux<CommonResult<String>> generateMindMap(@RequestBody @Valid AiMindMapGenerateReqVO generateReqVO) {
37 35 return mindMapService.generateMindMap(generateReqVO, getLoginUserId());
38 36 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/write/AiWriteController.java
... ... @@ -12,7 +12,6 @@ import io.swagger.v3.oas.annotations.Operation;
12 12 import io.swagger.v3.oas.annotations.Parameter;
13 13 import io.swagger.v3.oas.annotations.tags.Tag;
14 14 import jakarta.annotation.Resource;
15   -import jakarta.annotation.security.PermitAll;
16 15 import jakarta.validation.Valid;
17 16 import org.springframework.http.MediaType;
18 17 import org.springframework.security.access.prepost.PreAuthorize;
... ... @@ -32,7 +31,6 @@ public class AiWriteController {
32 31  
33 32 @PostMapping(value = "/generate-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
34 33 @Operation(summary = "写作生成(流式)", description = "流式返回,响应较快")
35   - @PermitAll // 解决 SSE 最终响应的时候,会被 Access Denied 拦截的问题
36 34 public Flux<CommonResult<String>> generateWriteContent(@RequestBody @Valid AiWriteGenerateReqVO generateReqVO) {
37 35 return writeService.generateWriteContent(generateReqVO, getLoginUserId());
38 36 }
... ...