🔒 安全问题处理
This commit is contained in:
parent
67f7615a18
commit
98d4870be3
@ -7,6 +7,7 @@ import com.rymcu.forest.core.result.GlobalResult;
|
|||||||
import com.rymcu.forest.core.result.ResultCode;
|
import com.rymcu.forest.core.result.ResultCode;
|
||||||
import com.rymcu.forest.enumerate.TransactionCode;
|
import com.rymcu.forest.enumerate.TransactionCode;
|
||||||
import com.rymcu.forest.web.api.exception.BaseApiException;
|
import com.rymcu.forest.web.api.exception.BaseApiException;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.shiro.authz.UnauthenticatedException;
|
import org.apache.shiro.authz.UnauthenticatedException;
|
||||||
import org.apache.shiro.authz.UnauthorizedException;
|
import org.apache.shiro.authz.UnauthorizedException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -39,9 +40,9 @@ public class BaseExceptionHandler {
|
|||||||
if (isAjax(request)) {
|
if (isAjax(request)) {
|
||||||
GlobalResult result = new GlobalResult();
|
GlobalResult result = new GlobalResult();
|
||||||
if (ex instanceof BaseApiException) {
|
if (ex instanceof BaseApiException) {
|
||||||
result.setCode(401);
|
result.setCode(((BaseApiException) ex).getCode());
|
||||||
result.setMessage("用户未登录");
|
result.setMessage(((BaseApiException) ex).getExtraMessage());
|
||||||
logger.info("用户未登录");
|
logger.info(result.getMessage());
|
||||||
} else if (ex instanceof UnauthenticatedException) {
|
} else if (ex instanceof UnauthenticatedException) {
|
||||||
result.setCode(1000001);
|
result.setCode(1000001);
|
||||||
result.setMessage("token错误");
|
result.setMessage("token错误");
|
||||||
@ -88,8 +89,8 @@ public class BaseExceptionHandler {
|
|||||||
FastJsonJsonView view = new FastJsonJsonView();
|
FastJsonJsonView view = new FastJsonJsonView();
|
||||||
Map<String, Object> attributes = new HashMap(2);
|
Map<String, Object> attributes = new HashMap(2);
|
||||||
if (ex instanceof BaseApiException) {
|
if (ex instanceof BaseApiException) {
|
||||||
attributes.put("code", "401");
|
attributes.put("code", ((BaseApiException) ex).getCode());
|
||||||
attributes.put("message", "用户未登录");
|
attributes.put("message", ((BaseApiException) ex).getExtraMessage());
|
||||||
} else if (ex instanceof UnauthenticatedException) {
|
} else if (ex instanceof UnauthenticatedException) {
|
||||||
attributes.put("code", "1000001");
|
attributes.put("code", "1000001");
|
||||||
attributes.put("message", "token错误");
|
attributes.put("message", "token错误");
|
||||||
@ -138,8 +139,8 @@ public class BaseExceptionHandler {
|
|||||||
String requestedWith = request.getHeader("x-requested-with");
|
String requestedWith = request.getHeader("x-requested-with");
|
||||||
if (requestedWith != null && "XMLHttpRequest".equalsIgnoreCase(requestedWith)) {
|
if (requestedWith != null && "XMLHttpRequest".equalsIgnoreCase(requestedWith)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
return false;
|
String contentType = request.getContentType();
|
||||||
}
|
return StringUtils.isNotBlank(contentType) && contentType.contains("application/json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.rymcu.forest.core.service.security;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.rymcu.forest.dto.TokenUser;
|
||||||
|
import com.rymcu.forest.jwt.def.JwtConstants;
|
||||||
|
import com.rymcu.forest.util.UserUtils;
|
||||||
|
import com.rymcu.forest.web.api.exception.BaseApiException;
|
||||||
|
import com.rymcu.forest.web.api.exception.ErrorCode;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户修改信息权限
|
||||||
|
*
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class SecurityAspect {
|
||||||
|
|
||||||
|
Logger logger = LoggerFactory.getLogger(SecurityAspect.class);
|
||||||
|
|
||||||
|
@Pointcut("@annotation(com.rymcu.forest.core.service.security.annotation.SecurityInterceptor)")
|
||||||
|
public void pointCut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户修改信息权限
|
||||||
|
*
|
||||||
|
* @param joinPoint 连接点
|
||||||
|
* @return 方法执行结果
|
||||||
|
* @throws Throwable 调用出错
|
||||||
|
*/
|
||||||
|
@Before(value = "pointCut()")
|
||||||
|
public void doBefore(JoinPoint joinPoint) throws BaseApiException {
|
||||||
|
logger.info("检查用户修改信息权限 start ...");
|
||||||
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
String idUser = "";
|
||||||
|
if (isAjax(request)) {
|
||||||
|
Object[] objects = joinPoint.getArgs();
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(objects[0]));
|
||||||
|
if (Objects.nonNull(jsonObject)) {
|
||||||
|
idUser = jsonObject.getString("idUser");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Map params = getParams(request);
|
||||||
|
if (params.isEmpty()) {
|
||||||
|
params = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||||
|
} else {
|
||||||
|
params.putAll((Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE));
|
||||||
|
}
|
||||||
|
idUser = (String) params.get("idUser");
|
||||||
|
}
|
||||||
|
if (Objects.nonNull(idUser)) {
|
||||||
|
String authHeader = request.getHeader(JwtConstants.AUTHORIZATION);
|
||||||
|
if (StringUtils.isNotBlank(authHeader)) {
|
||||||
|
TokenUser tokenUser = UserUtils.getTokenUser(authHeader);
|
||||||
|
if (Objects.nonNull(tokenUser)) {
|
||||||
|
if (!idUser.equals(tokenUser.getIdUser().toString())) {
|
||||||
|
throw new BaseApiException(ErrorCode.ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BaseApiException(ErrorCode.ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BaseApiException(ErrorCode.ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
logger.info("检查用户修改信息权限 end ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getParams(HttpServletRequest request) {
|
||||||
|
Map<String, String> paramsMap = new HashMap<>(10);
|
||||||
|
Enumeration<String> paraNames = request.getParameterNames();
|
||||||
|
while (paraNames.hasMoreElements()) {
|
||||||
|
String key = paraNames.nextElement();
|
||||||
|
if ("password".equals(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
paramsMap.put(key, request.getParameter(key));
|
||||||
|
}
|
||||||
|
return paramsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAjax(HttpServletRequest request) {
|
||||||
|
String requestedWith = request.getHeader("x-requested-with");
|
||||||
|
if (requestedWith != null && "XMLHttpRequest".equalsIgnoreCase(requestedWith)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String contentType = request.getContentType();
|
||||||
|
return StringUtils.isNotBlank(contentType) && contentType.contains("application/json");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.rymcu.forest.core.service.security.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全拦截器
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface SecurityInterceptor {
|
||||||
|
}
|
@ -66,10 +66,10 @@ public class RestAuthTokenInterceptor implements HandlerInterceptor {
|
|||||||
request.setAttribute(JwtConstants.CURRENT_TOKEN_CLAIMS, claims);
|
request.setAttribute(JwtConstants.CURRENT_TOKEN_CLAIMS, claims);
|
||||||
//如果token验证成功,将token对应的用户id存在request中,便于之后注入
|
//如果token验证成功,将token对应的用户id存在request中,便于之后注入
|
||||||
request.setAttribute(JwtConstants.CURRENT_USER_NAME, model.getUsername());
|
request.setAttribute(JwtConstants.CURRENT_USER_NAME, model.getUsername());
|
||||||
|
String uri = request.getRequestURI();
|
||||||
// 判断是否为后台接口或财政划转接口
|
// 判断是否为后台接口或财政划转接口
|
||||||
String adminApi = "/admin";
|
String adminApi = "/admin";
|
||||||
String transactionApi = "/transaction";
|
String transactionApi = "/transaction";
|
||||||
String uri = request.getRequestURI();
|
|
||||||
if (uri.contains(adminApi) || uri.contains(transactionApi)) {
|
if (uri.contains(adminApi) || uri.contains(transactionApi)) {
|
||||||
// 判断管理员权限
|
// 判断管理员权限
|
||||||
boolean hasPermission = userMapper.hasAdminPermission(model.getUsername());
|
boolean hasPermission = userMapper.hasAdminPermission(model.getUsername());
|
||||||
|
@ -2,6 +2,7 @@ package com.rymcu.forest.web.api.exception;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务(业务)异常如“ 账号或密码错误 ”,该异常只做INFO级别的日志记录 @see WebMvcConfigurer
|
* 服务(业务)异常如“ 账号或密码错误 ”,该异常只做INFO级别的日志记录 @see WebMvcConfigurer
|
||||||
|
* @author ronger
|
||||||
*/
|
*/
|
||||||
public class BaseApiException extends Exception {
|
public class BaseApiException extends Exception {
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package com.rymcu.forest.web.api.user;
|
|||||||
|
|
||||||
import com.rymcu.forest.core.result.GlobalResult;
|
import com.rymcu.forest.core.result.GlobalResult;
|
||||||
import com.rymcu.forest.core.result.GlobalResultGenerator;
|
import com.rymcu.forest.core.result.GlobalResultGenerator;
|
||||||
|
import com.rymcu.forest.core.service.security.annotation.SecurityInterceptor;
|
||||||
import com.rymcu.forest.dto.*;
|
import com.rymcu.forest.dto.*;
|
||||||
import com.rymcu.forest.entity.UserExtend;
|
import com.rymcu.forest.entity.UserExtend;
|
||||||
import com.rymcu.forest.service.UserService;
|
import com.rymcu.forest.service.UserService;
|
||||||
@ -21,36 +22,42 @@ public class UserInfoController {
|
|||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@GetMapping("/detail/{idUser}")
|
@GetMapping("/detail/{idUser}")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult detail(@PathVariable Integer idUser) {
|
public GlobalResult detail(@PathVariable Integer idUser) {
|
||||||
Map map = userService.findUserInfo(idUser);
|
Map map = userService.findUserInfo(idUser);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/check-nickname")
|
@GetMapping("/check-nickname")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult checkNickname(@RequestParam Integer idUser, @RequestParam String nickname) {
|
public GlobalResult checkNickname(@RequestParam Integer idUser, @RequestParam String nickname) {
|
||||||
Map map = userService.checkNickname(idUser,nickname);
|
Map map = userService.checkNickname(idUser,nickname);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/update")
|
@PatchMapping("/update")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult updateUserInfo(@RequestBody UserInfoDTO user) {
|
public GlobalResult updateUserInfo(@RequestBody UserInfoDTO user) {
|
||||||
Map map = userService.updateUserInfo(user);
|
Map map = userService.updateUserInfo(user);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/update-extend")
|
@PatchMapping("/update-extend")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult updateUserExtend(@RequestBody UserExtend userExtend) {
|
public GlobalResult updateUserExtend(@RequestBody UserExtend userExtend) {
|
||||||
Map map = userService.updateUserExtend(userExtend);
|
Map map = userService.updateUserExtend(userExtend);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/update-email")
|
@PatchMapping("/update-email")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult updateEmail(@RequestBody ChangeEmailDTO changeEmailDTO) {
|
public GlobalResult updateEmail(@RequestBody ChangeEmailDTO changeEmailDTO) {
|
||||||
Map map = userService.updateEmail(changeEmailDTO);
|
Map map = userService.updateEmail(changeEmailDTO);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/update-password")
|
@PatchMapping("/update-password")
|
||||||
|
@SecurityInterceptor
|
||||||
public GlobalResult updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO) {
|
public GlobalResult updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO) {
|
||||||
Map map = userService.updatePassword(updatePasswordDTO);
|
Map map = userService.updatePassword(updatePasswordDTO);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
|
Loading…
Reference in New Issue
Block a user