feat(security): 为 Dify 相关操作添加权限控制- 在 V1ChatController、V1ServerController 和 V1WorkflowController 中添加了 @PreAuthorize 注解

- 为不同操作定义了相应的权限标识,如 dify:chat:conversations、dify:app:list 等
-通过 Spring Security 的权限管理功能,实现了对 Dify 相关操作的细粒度权限控制
This commit is contained in:
vertoryao 2025-07-13 23:50:22 +08:00
parent 626a087813
commit 83fabb1383
3 changed files with 28 additions and 3 deletions

View File

@ -80,6 +80,7 @@ public class V1ChatController {
* @return 会话列表
*/
@PostMapping("/conversations/{appId}")
@PreAuthorize("hasAuthority('dify:chat:conversations')")
public DifyPageResult<MessageConversationsResponse> conversations(
@RequestBody MessageConversationsRequest request,
@PathVariable String appId
@ -96,6 +97,7 @@ public class V1ChatController {
* @return 消息列表
*/
@PostMapping("/messages/{appid}")
@PreAuthorize("hasAuthority('dify:chat:messages')")
public DifyPageResult<MessagesResponseVO> messages(
@RequestBody MessagesRequest request,
@PathVariable String appid
@ -112,6 +114,7 @@ public class V1ChatController {
* @param taskId 任务id
*/
@PatchMapping("/stream/stop")
@PreAuthorize("hasAuthority('dify:chat:stop')")
public void stopMessagesStream(@RequestParam String taskId, @RequestParam String appId) {
String apiKey = appEntityService.getApikey(appId);
String userId = SecurityUtil.getUserInfo().id.toString();
@ -124,6 +127,7 @@ public class V1ChatController {
* @param conversationId 会话id
*/
@DeleteMapping("/conversation")
@PreAuthorize("hasAuthority('dify:chat:delete')")
@OperationLogAnnotation(content = "'dify对话'", operationType = "删除")
public Map<String, String> deleteConversation(@RequestParam String conversationId, @RequestParam String appId) {
String apiKey = appEntityService.getApikey(appId);
@ -143,6 +147,7 @@ public class V1ChatController {
* @return
*/
@GetMapping("/messages/suggested")
@PreAuthorize("hasAuthority('dify:chat:suggested')")
public List<String> messagesSuggested(String messageId,String appId){
String apiKey = appEntityService.getApikey(appId);
String userId = SecurityUtil.getUserInfo().id.toString();
@ -155,6 +160,7 @@ public class V1ChatController {
* @return
*/
@GetMapping("/parameters/{appid}")
@PreAuthorize("hasAuthority('dify:chat:parameters')")
public AppParametersResponseVO parameters(@PathVariable String appid){
String apiKey = appEntityService.getApikey(appid);
return ExceptionUtil.difyException(()->difyChat.parameters(apiKey));

View File

@ -40,6 +40,7 @@ public class V1ServerController {
* @return
*/
@GetMapping("/apps")
@PreAuthorize("hasAuthority('dify:app:list')")
public List<AppEntity> getApps(String mode, String name, Integer type) {
return appEntityService.getApps(mode, name, type);
}
@ -50,6 +51,7 @@ public class V1ServerController {
* @return
*/
@GetMapping("/{id}")
@PreAuthorize("hasAuthority('dify:app:detail')")
public AppsResponse getApp(@PathVariable("id") String id) {
return difyServer.app(id);
}
@ -60,6 +62,7 @@ public class V1ServerController {
* @return
*/
@GetMapping("/api-key/{id}")
@PreAuthorize("hasAuthority('dify:app:api-key')")
public List<ApiKeyResponse> getAppApiKey(@PathVariable("id") String id) {
return difyServer.getAppApiKey(id);
}
@ -70,6 +73,7 @@ public class V1ServerController {
* @return
*/
@PostMapping("/api-key/init/{id}")
@PreAuthorize("hasAuthority('dify:app:api-key')")
public List<ApiKeyResponse> initAppApiKey(@PathVariable("id") String id) {
return difyServer.initAppApiKey(id);
}
@ -79,6 +83,7 @@ public class V1ServerController {
* @return
*/
@GetMapping("/api-key/dataset")
@PreAuthorize("hasAuthority('dify:app:api-key')")
public List<DatasetApiKeyResponse> getDatasetApiKey() {
return difyServer.getDatasetApiKey();
}
@ -88,6 +93,7 @@ public class V1ServerController {
* @return
*/
@PostMapping("/api-key/dataset/init")
@PreAuthorize("hasAuthority('dify:dataset:api-key')")
public List<DatasetApiKeyResponse> initDatasetApiKey() {
return difyServer.initDatasetApiKey();
}
@ -99,6 +105,7 @@ public class V1ServerController {
* @return
*/
@PostMapping("/app/{id}/toggle")
@PreAuthorize("hasAuthority('dify:dataset:api-key')")
@OperationLogAnnotation(content = "'dify服务启用状态'", operationType = "更新")
public boolean enabledApp(@PathVariable String id) {
return appEntityService.enabledApp(id);
@ -109,6 +116,7 @@ public class V1ServerController {
* @return
*/
@GetMapping("/apps/enabled")
@PreAuthorize("hasAuthority('dify:app:list')")
@DataPermission
public List<AppEntity> getEnableApps() {
LambdaQueryWrapper<AppEntity> queryWrapper = new LambdaQueryWrapper<>();
@ -122,12 +130,14 @@ public class V1ServerController {
* @return
*/
@GetMapping("/apps/type")
@PreAuthorize("hasAuthority('dify:app:list')")
// @DataPermission
public List<AppEntity> getAppsByAppType(Integer appType){
return appEntityService.selectByAppType(appType);
}
@PostMapping("/link")
@PreAuthorize("hasAuthority('dify:app:link')")
public ResponseEntity<String> link(@RequestBody WorkflowDeptDto workflowDeptDto) {
List<WorkflowDept> workflowDepts = new ArrayList<>();
for (Long deptId: workflowDeptDto.getDeptIds()) {
@ -141,6 +151,7 @@ public class V1ServerController {
}
@GetMapping("/link/{workflowId}")
@PreAuthorize("hasAuthority('dify:app:link')")
public List<WorkflowDept> linked(@PathVariable String workflowId) {
return workflowDeptService.lambdaQuery().eq(WorkflowDept::getWorkflowId, workflowId).list();
}

View File

@ -42,6 +42,7 @@ public class V1WorkflowController {
* @return
*/
@PostMapping("/run/{appId}")
@PreAuthorize("hasAuthority('dify:workflow:run')")
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
public WorkflowRunResponse runWorkflow(@RequestBody WorkflowRunRequest request, @PathVariable String appId) {
request.setUserId(SecurityUtil.getUserInfo().id.toString());
@ -55,6 +56,7 @@ public class V1WorkflowController {
* @return
*/
@PostMapping(value = "/run/stream/{appId}", produces= MediaType.TEXT_EVENT_STREAM_VALUE)
@PreAuthorize("hasAuthority('dify:workflow:run')")
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
public Flux<WorkflowRunStreamResponse> runWorkflowStream(@RequestBody WorkflowRunRequest request, @PathVariable String appId) {
String apiKey =appEntityService.getApikey(appId);
@ -70,6 +72,7 @@ public class V1WorkflowController {
* @return
*/
@PatchMapping("/stop/{appId}")
@PreAuthorize("hasAuthority('dify:workflow:stop')")
@OperationLogAnnotation(content = "'dify工作流'", operationType = "运行")
public WorkflowStopResponse stopWorkflowStream(String taskId, @PathVariable String appId) {
String apiKey =appEntityService.getApikey(appId);
@ -78,12 +81,13 @@ public class V1WorkflowController {
}
/**
* 获取工作流信息
* 获取工作流运行详情
*
* @param workflowRunId
* @return
*/
@GetMapping("/info/{appId}")
@PreAuthorize("hasAuthority('dify:workflow:info')")
public WorkflowInfoResponse info(String workflowRunId, @PathVariable String appId) {
String apiKey =appEntityService.getApikey(appId);
return ExceptionUtil.difyException(() -> difyWorkflow.info(workflowRunId, apiKey));
@ -96,11 +100,11 @@ public class V1WorkflowController {
* @return
*/
@PostMapping("/logs/{appId}")
@PreAuthorize("hasAuthority('dify:workflow:logs')")
public DifyPageResult<WorkflowLogs> logs(@RequestBody WorkflowLogsRequest request, @PathVariable String appId) {
String apiKey = appEntityService.getApikey(appId);
request.setApiKey(apiKey);
final DifyPageResult<WorkflowLogs> logs = difyWorkflow.logs(request);
return logs;
return difyWorkflow.logs(request);
}
/**
@ -110,6 +114,7 @@ public class V1WorkflowController {
* @return
*/
@GetMapping("/list/{appId}")
@PreAuthorize("hasAuthority('dify:workflow:logs')")
@DataPermission
public List<WorkflowData> list(@PathVariable String appId){
return difyWorkflowService.list(new QueryWrapper<WorkflowData>().eq("app_id",appId));
@ -122,6 +127,7 @@ public class V1WorkflowController {
* @return
*/
@GetMapping("/detail/{id}")
@PreAuthorize("hasAuthority('dify:workflow:detail')")
@DataPermission
public WorkflowData detail(@PathVariable Long id){
return difyWorkflowService.detail(id);
@ -134,6 +140,7 @@ public class V1WorkflowController {
* @return
*/
@DeleteMapping("/delete/{id}")
@PreAuthorize("hasAuthority('dify:workflow:delete')")
@OperationLogAnnotation(content = "'dify工作流日志'", operationType = "删除")
public boolean delete(@PathVariable Long id){
return difyWorkflowService.delete(id);
@ -146,6 +153,7 @@ public class V1WorkflowController {
* @return
*/
@GetMapping("/query")
@PreAuthorize("hasAuthority('dify:workflow:list')")
@DataPermission
public Page<WorkflowData> query(Page<WorkflowData> page){
return difyWorkflowService.query(page);