✨ 添加新特性。@Inner 内部调用校验
This commit is contained in:
1 parent
d32090bf51
commit
444ccb4bd1
17 files changed
+169
-40
No files matched your search
+2
-2
@@ -31,9 +31,9 @@ import java.io.Serializable;
|
||||
* @param <T>
|
||||
* @author lengleng
|
||||
*/
|
||||
@ToString
|
||||
@Accessors(chain=true)
|
||||
@Builder
|
||||
@ToString
|
||||
@Accessors(chain = true)
|
||||
@AllArgsConstructor
|
||||
public class R<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
+3
@@ -26,12 +26,15 @@ import lombok.AllArgsConstructor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/6/28
|
||||
* <p>
|
||||
* 日志自动配置
|
||||
*/
|
||||
@EnableAsync
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnWebApplication
|
||||
|
||||
+2
-1
@@ -27,14 +27,15 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 操作日志使用spring event异步入库
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Aspect
|
||||
public class SysLogAspect {
|
||||
|
||||
@Around("@annotation(sysLog)")
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ package com.pig4cloud.pigx.common.log.event;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
@@ -42,6 +43,6 @@ public class SysLogListener {
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveSysLog(SysLogEvent event) {
|
||||
SysLog sysLog = (SysLog) event.getSource();
|
||||
remoteLogService.saveLog(sysLog);
|
||||
remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/11/26
|
||||
* <p>
|
||||
* 服务调用不鉴权注解
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Inner {
|
||||
|
||||
/**
|
||||
* 是否AOP统一处理
|
||||
*
|
||||
* @return false, true
|
||||
*/
|
||||
boolean value() default true;
|
||||
|
||||
/**
|
||||
* 需要特殊判空的字段(预留)
|
||||
*
|
||||
* @return {}
|
||||
*/
|
||||
String[] field() default {};
|
||||
}
|
||||
+11
-5
@@ -19,10 +19,10 @@ package com.pig4cloud.pigx.common.security.component;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstant;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
@@ -51,7 +51,10 @@ public class GlobalExceptionHandlerResolver {
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public R handleGlobalException(Exception e) {
|
||||
log.error("全局异常信息 ex={}", e.getMessage(), e);
|
||||
return new R<>(e);
|
||||
return R.builder()
|
||||
.msg(e.getLocalizedMessage())
|
||||
.code(CommonConstant.FAIL)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,9 +66,12 @@ public class GlobalExceptionHandlerResolver {
|
||||
@ExceptionHandler(AccessDeniedException.class)
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public R handleAccessDeniedException(AccessDeniedException e) {
|
||||
log.error("拒绝授权异常信息 ex={}",e.getLocalizedMessage(),e);
|
||||
String msg = SpringSecurityMessageSource.getAccessor()
|
||||
.getMessage("AbstractAccessDecisionManager.accessDenied"
|
||||
, e.getMessage());
|
||||
log.error("拒绝授权异常信息 ex={}", msg, e);
|
||||
return R.builder()
|
||||
.msg(e.getLocalizedMessage())
|
||||
.msg(msg)
|
||||
.code(CommonConstant.FAIL)
|
||||
.build();
|
||||
}
|
||||
@@ -80,7 +86,7 @@ public class GlobalExceptionHandlerResolver {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public R handleBodyValidException(MethodArgumentNotValidException exception) {
|
||||
List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
|
||||
log.error("参数绑定异常,ex = {}",fieldErrors.get(0).getDefaultMessage());
|
||||
log.error("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
|
||||
return R.builder()
|
||||
.msg(fieldErrors.get(0).getDefaultMessage())
|
||||
.code(CommonConstant.FAIL)
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.security.component;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/11/26
|
||||
* <p>
|
||||
* 服务间接口不鉴权处理逻辑
|
||||
*/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class PigxSecurityInnerAspect {
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@Around("@annotation(inner)")
|
||||
public Object around(ProceedingJoinPoint point, Inner inner) throws Throwable {
|
||||
String header = request.getHeader(SecurityConstants.FROM);
|
||||
if (inner.value() && !StrUtil.equals(SecurityConstants.FROM_IN, header)) {
|
||||
log.warn("访问接口 {} 没有权限", point.getSignature().getName());
|
||||
throw new AccessDeniedException("Access is denied");
|
||||
}
|
||||
return point.proceed();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
|
||||
*/
|
||||
@Override
|
||||
public UserDetails loadUserBySocial(String inStr) throws UsernameNotFoundException {
|
||||
return getUserDetails(remoteUserService.social(inStr));
|
||||
return getUserDetails(remoteUserService.social(inStr, SecurityConstants.FROM_IN));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,9 +10,9 @@ security:
|
||||
- '/actuator/**'
|
||||
- '/v2/api-docs'
|
||||
- '/user/info/*'
|
||||
- '/social/info/**'
|
||||
- '/social/info/*'
|
||||
- '/mobile/*'
|
||||
- '/log/**'
|
||||
- '/log/save'
|
||||
|
||||
# 数据源
|
||||
spring:
|
||||
|
||||
+5
-2
@@ -21,11 +21,13 @@ package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.admin.api.feign.factory.RemoteLogServiceFallbackFactory;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstant;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -37,8 +39,9 @@ public interface RemoteLogService {
|
||||
* 保存日志
|
||||
*
|
||||
* @param sysLog 日志实体
|
||||
* @param from 是否内部调用
|
||||
* @return succes、false
|
||||
*/
|
||||
@PostMapping("/log")
|
||||
R<Boolean> saveLog(@RequestBody SysLog sysLog);
|
||||
@PostMapping("/log/save")
|
||||
R<Boolean> saveLog(@RequestBody SysLog sysLog, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
}
|
||||
+3
-1
@@ -53,10 +53,12 @@ public interface RemoteUserService {
|
||||
* 通过社交账号或手机号查询用户、角色信息
|
||||
*
|
||||
* @param inStr appid@code
|
||||
* @param from 调用标志
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/social/info/{inStr}")
|
||||
R<UserInfo> social(@PathVariable("inStr") String inStr);
|
||||
R<UserInfo> social(@PathVariable("inStr") String inStr
|
||||
, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
|
||||
/**
|
||||
* 查询上级部门的用户信息
|
||||
|
||||
+2
-1
@@ -40,10 +40,11 @@ public class RemoteLogServiceFallbackImpl implements RemoteLogService {
|
||||
* 保存日志
|
||||
*
|
||||
* @param sysLog
|
||||
* @param from
|
||||
* @return R
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> saveLog(SysLog sysLog) {
|
||||
public R<Boolean> saveLog(SysLog sysLog, String from) {
|
||||
log.error("feign 插入日志失败", cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
+2
-1
@@ -56,10 +56,11 @@ public class RemoteUserServiceFallbackImpl implements RemoteUserService {
|
||||
* 通过社交账号查询用户、角色信息
|
||||
*
|
||||
* @param inStr appid@code
|
||||
* @param from 内外标志
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<UserInfo> social(String inStr) {
|
||||
public R<UserInfo> social(String inStr, String from) {
|
||||
log.error("feign 查询用户信息失败:{}", inStr, cause);
|
||||
return null;
|
||||
}
|
||||
|
||||
+3
-1
@@ -26,6 +26,7 @@ import com.pig4cloud.pigx.admin.api.entity.SysLog;
|
||||
import com.pig4cloud.pigx.admin.api.vo.PreLogVo;
|
||||
import com.pig4cloud.pigx.admin.service.SysLogService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@@ -79,7 +80,8 @@ public class LogController {
|
||||
* @param sysLog 日志实体
|
||||
* @return success/false
|
||||
*/
|
||||
@PostMapping
|
||||
@Inner
|
||||
@PostMapping("/save")
|
||||
public R save(@Valid @RequestBody SysLog sysLog) {
|
||||
return new R<>(sysLogService.save(sysLog));
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
|
||||
import com.pig4cloud.pigx.admin.service.SysSocialDetailsService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -111,6 +112,7 @@ public class SysSocialDetailsController {
|
||||
* @param inStr appid@code
|
||||
* @return
|
||||
*/
|
||||
@Inner
|
||||
@GetMapping("/info/{inStr}")
|
||||
public R getUserInfo(@PathVariable String inStr) {
|
||||
return new R<>(sysSocialDetailsService.getUserInfo(inStr));
|
||||
|
||||
+25
-21
@@ -19,16 +19,15 @@
|
||||
|
||||
package com.pig4cloud.pigx.admin.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.service.SysUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@@ -51,34 +50,39 @@ public class UserController {
|
||||
private final SysUserService userService;
|
||||
|
||||
/**
|
||||
* 获取当前用户信息(角色、权限)
|
||||
* 并且异步初始化用户部门信息
|
||||
* 获取当前用户全部信息
|
||||
*
|
||||
* @param from 请求标志,该接口会被 auth、 前端调用
|
||||
* @param username 用户名
|
||||
* @return 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
@GetMapping(value = {"/info", "/info/{username}"})
|
||||
public R user(@PathVariable(required = false) String username,
|
||||
@RequestHeader(required = false) String from) {
|
||||
// 查询用户不为空时判断是不是内部请求
|
||||
if (StrUtil.isNotBlank(username) && !StrUtil.equals(SecurityConstants.FROM_IN, from)) {
|
||||
return new R<>(null, "error");
|
||||
}
|
||||
//为空时查询当前用户
|
||||
if (StrUtil.isBlank(username)) {
|
||||
username = SecurityUtils.getUser().getUsername();
|
||||
}
|
||||
@GetMapping(value = {"/info"})
|
||||
public R info() {
|
||||
String username = SecurityUtils.getUser().getUsername();
|
||||
SysUser sysUser = userService.getOne(Wrappers.<SysUser>query()
|
||||
.lambda().eq(SysUser::getUsername, username));
|
||||
if (sysUser == null) {
|
||||
return new R<>();
|
||||
return new R<>(Boolean.FALSE, "获取当前用户信息失败");
|
||||
}
|
||||
return new R<>(userService.findUserInfo(sysUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过ID查询当前用户信息
|
||||
* 获取指定用户全部信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
@Inner
|
||||
@GetMapping("/info/{username}")
|
||||
public R info(@PathVariable String username) {
|
||||
SysUser user = userService.getOne(Wrappers.<SysUser>query()
|
||||
.lambda().eq(SysUser::getUsername, username));
|
||||
if (user == null) {
|
||||
return new R<>(Boolean.FALSE, String.format("用户信息为空 %s", username));
|
||||
}
|
||||
return new R<>(userService.findUserInfo(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过ID查询用户信息
|
||||
*
|
||||
* @param id ID
|
||||
* @return 用户信息
|
||||
@@ -169,7 +173,7 @@ public class UserController {
|
||||
|
||||
/**
|
||||
* @param username 用户名称
|
||||
* @return
|
||||
* @return 上级部门用户列表
|
||||
*/
|
||||
@GetMapping("/ancestor/{username}")
|
||||
public R listAncestorUsers(@PathVariable String username) {
|
||||
|
||||
+2
-1
@@ -26,7 +26,8 @@ import org.springframework.cloud.client.SpringCloudApplication;
|
||||
* @date 2018年11月15日17:06:26
|
||||
* <p>
|
||||
* 单点登录客户端
|
||||
* 访问:http://localhost:4040/sso1/
|
||||
* 1. 启动实例访问:http://localhost:4040/sso1/ 提示登录,然后获取到用户信息
|
||||
* 2. 再启动一个实例: http://localhost:4040/sso1/ 不需要登录即可获取当前用户信息
|
||||
*/
|
||||
@EnableOAuth2Sso
|
||||
@SpringCloudApplication
|
||||
|
||||
Reference in new issue
Block a user