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

View File

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

View File

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