diff --git a/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java b/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java index e93c8cb..aa6ed45 100644 --- a/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java +++ b/src/main/java/com/huoran/iasf/common/aop/aspect/NoRepeatSubmitAop.java @@ -1,6 +1,7 @@ package com.huoran.iasf.common.aop.aspect; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import com.huoran.iasf.common.aop.annotation.NoRepeatSubmit; import com.huoran.iasf.common.exception.BusinessException; @@ -16,6 +17,7 @@ import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; @@ -44,17 +46,24 @@ public class NoRepeatSubmitAop { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); + HttpServletResponse response = attributes.getResponse(); String token = request.getHeader(Constant.ACCESS_TOKEN); //如果header中不存在token,则从参数中获取token if (StringUtils.isEmpty(token)) { token = request.getParameter(Constant.ACCESS_TOKEN); } if (StringUtils.isEmpty(token)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); throw new BusinessException(BaseResponseCode.TOKEN_ERROR); } // 校验并解析token,如果token过期或者篡改,则会返回null Claims claims = checkJWT(token); if (null == claims) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); throw new BusinessException(BaseResponseCode.TOKEN_ERROR); } String key = token + "-" + request.getServletPath(); diff --git a/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java index ed67b03..17b086f 100644 --- a/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java +++ b/src/main/java/com/huoran/iasf/common/exception/code/BaseResponseCode.java @@ -31,7 +31,7 @@ public enum BaseResponseCode implements ResponseCodeInterface { EXCEL_FILE_INVALID(10004, "上传excel文件错误!"), VALID_EXCEPTION(10003, "参数格式校验异常!"), OPERATION_ERROR(10002, "操作失败"), - SYSTEM_BUSY(10001, "系统繁忙,请稍候再试"), + SYSTEM_BUSY(500, "系统繁忙,请稍候再试"), SUCCESS(200, "success"), EXCEL_FILE_FORMAT_ERROR(40007, "请根据模板使用说明录入正确的用户信息!"), @@ -40,7 +40,7 @@ public enum BaseResponseCode implements ResponseCodeInterface { NOT_ACCOUNT(401004, "该用户不存在,请先注册"), USER_LOCK(401005, "该用户已被锁定,请联系运营人员"), PASSWORD_ERROR(401006, "用户名或密码错误"), - METHOD_ARGUMENT_NOT_VALID_EXCEPTION(401007, "方法参数校验异常"), + METHOD_ARGUMENT_NOT_VALID_EXCEPTION(400, "请求参数有误"), UNAUTHORIZED_ERROR(401008, "权鉴校验不通过"), ROLE_PERMISSION_RELATION(401009, "该菜单权限存在子集关联,不允许删除"), OLD_PASSWORD_ERROR(401010, "旧密码不正确"), diff --git a/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java b/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java index 5be1cef..d2eebb7 100644 --- a/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java +++ b/src/main/java/com/huoran/iasf/common/exception/handler/RestExceptionHandler.java @@ -7,14 +7,17 @@ import com.huoran.iasf.common.utils.R; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authz.AuthorizationException; +import org.springframework.http.HttpStatus; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; +import javax.validation.ValidationException; import java.util.HashMap; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -34,12 +37,21 @@ public class RestExceptionHandler { * 系统繁忙,请稍候再试" */ @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.NOT_FOUND) public R handleException(Exception e) { log.error("Exception,exception:{}", e, e); return R.getResult(BaseResponseCode.SYSTEM_BUSY); } + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public R illegalArgumentException(IllegalArgumentException e) { + log.error("Exception,exception:{}", e, e); + return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION); + } + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) public R authenticationException(AuthenticationException e) { log.error("Exception,exception:{}", e, e); // throw new BusinessException(BaseResponseCode.TOKEN_ERROR); @@ -50,6 +62,7 @@ public class RestExceptionHandler { * 自定义全局异常处理 */ @ExceptionHandler(value = BusinessException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) public R businessExceptionHandler(BusinessException e) { log.error("Exception,exception:{}", e, e); BaseResponseCode em = e.getBaseResponseCode(); @@ -60,6 +73,7 @@ public class RestExceptionHandler { * 没有权限 返回403视图 */ @ExceptionHandler(value = AuthorizationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) public R errorPermission(AuthorizationException e) { log.error("Exception,exception:{}", e, e); return new R(BaseResponseCode.UNAUTHORIZED_ERROR); @@ -70,6 +84,7 @@ public class RestExceptionHandler { * 处理参数格式校验异常 */ @ExceptionHandler(value = MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) public R handleValidException(MethodArgumentNotValidException e){ log.error("参数格式校验异常"); BindingResult bindingResult = e.getBindingResult(); @@ -87,6 +102,7 @@ public class RestExceptionHandler { * 处理Validated List 异常 */ @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) public R handle(ConstraintViolationException exception) { log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", exception, exception); Set> violations = exception.getConstraintViolations(); @@ -98,4 +114,11 @@ public class RestExceptionHandler { return R.getResult(BaseResponseCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getCode(), builder.toString()); } + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public R handle(ValidationException e) { + log.error("Exception,exception:{}", e, e); + return new R(404, e.getMessage()); + } + } diff --git a/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java b/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java index 87702ac..da1c07c 100644 --- a/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java +++ b/src/main/java/com/huoran/iasf/common/filter/AuthFilter.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import javax.servlet.*; @@ -75,16 +76,22 @@ public class AuthFilter implements Filter { } //token为空返回 if (StringUtils.isBlank(token)) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setCharacterEncoding("utf-8"); + resp.setContentType(MediaType.APPLICATION_JSON_VALUE); request.setAttribute("filterError", new BusinessException(BaseResponseCode.TOKEN_ERROR)); // 指定处理该请求的处理器 - request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, resp); } // 校验并解析token,如果token过期或者篡改,则会返回null Claims claims = checkJWT(token); if (null == claims) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + resp.setCharacterEncoding("utf-8"); + resp.setContentType(MediaType.APPLICATION_JSON_VALUE); request.setAttribute("filterError", new BusinessException(BaseResponseCode.TOKEN_ERROR)); // 指定处理该请求的处理器 - request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, resp); }else { // 校验通过后,设置用户信息到request里,在Controller中从Request域中获取用户信息 request.setAttribute(USER_ID_KEY, claims.get(USER_ID_KEY)); diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java b/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java index 819645c..4e8fa7c 100644 --- a/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomAccessControlFilter.java @@ -15,6 +15,7 @@ import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.AccessControlFilter; import org.apache.shiro.web.util.WebUtils; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; @@ -65,6 +66,7 @@ public class CustomAccessControlFilter extends AccessControlFilter { protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; // try { + HttpServletResponse response = (HttpServletResponse) servletResponse; Subject subject = getSubject(servletRequest, servletResponse); System.out.println(subject.isAuthenticated() + ""); System.out.println(HttpContextUtils.isAjaxRequest(request)); @@ -78,16 +80,22 @@ public class CustomAccessControlFilter extends AccessControlFilter { token = request.getParameter(Constant.ACCESS_TOKEN); } if (StringUtils.isEmpty(token)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); request.setAttribute("filterError", new BusinessException(BaseResponseCode.TOKEN_ERROR)); // 指定处理该请求的处理器 - request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, servletResponse); + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); } // 校验并解析token,如果token过期或者篡改,则会返回null Claims claims = checkJWT(token); if (null == claims) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setCharacterEncoding("utf-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); request.setAttribute("filterError", new BusinessException(BaseResponseCode.TOKEN_ERROR)); // 指定处理该请求的处理器 - request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, servletResponse); + request.getRequestDispatcher(Constant.ERROR_CONTROLLER_PATH).forward(request, response); }else { UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(token, token); getSubject(servletRequest, servletResponse).login(usernamePasswordToken); diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java b/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java index 254c6e8..002dca8 100644 --- a/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomHashedCredentialsMatcher.java @@ -31,7 +31,8 @@ public class CustomHashedCredentialsMatcher extends SimpleCredentialsMatcher { String accessToken = (String) token.getPrincipal(); if (!redisDb.exists(userTokenPrefix + accessToken)) { SecurityUtils.getSubject().logout(); - throw new BusinessException(BaseResponseCode.TOKEN_ERROR); +// throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + return false; } return true; } diff --git a/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java b/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java index 4a55d25..2bf97fc 100644 --- a/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java +++ b/src/main/java/com/huoran/iasf/common/shiro/CustomRealm.java @@ -13,6 +13,7 @@ import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; @@ -61,11 +62,12 @@ public class CustomRealm extends AuthorizingRealm { String sessionInfoStr = redisDb.get(userTokenPrefix + principalCollection.getPrimaryPrincipal()); if (StringUtils.isEmpty(sessionInfoStr)) { - throw new BusinessException(BaseResponseCode.TOKEN_ERROR); +// throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + throw new AuthorizationException(); } JSONObject redisSession = JSON.parseObject(sessionInfoStr); if (redisSession == null) { - throw new BusinessException(BaseResponseCode.TOKEN_ERROR); + throw new AuthorizationException(); } if (redisSession.get(Constant.ROLES_KEY) != null) { diff --git a/src/main/java/com/huoran/iasf/controller/SysColumnController.java b/src/main/java/com/huoran/iasf/controller/SysColumnController.java index 3545e55..6d79e38 100644 --- a/src/main/java/com/huoran/iasf/controller/SysColumnController.java +++ b/src/main/java/com/huoran/iasf/controller/SysColumnController.java @@ -60,13 +60,13 @@ public class SysColumnController { @PostMapping("/listWithTree") @ApiOperation(value = "栏目树结构", response = SysColumn.class) - public R listWithTree(@RequestBody @Validated PaginationColumnReqVO sysColumn) { + public R listWithTree(@RequestBody @Valid PaginationColumnReqVO sysColumn) { return R.success(service.listWithTree(sysColumn)); } @PostMapping("/listWithTreeMenuVisible") @ApiOperation(value = "栏目树结构(前台可见,只展示试单可见的栏目)", response = SysColumn.class) - public R listWithTreeMenuVisible(@RequestBody @Validated PaginationColumnReqVO sysColumn) { + public R listWithTreeMenuVisible(@RequestBody @Valid PaginationColumnReqVO sysColumn) { return R.success(service.listWithTreeMenuVisible(sysColumn)); } diff --git a/src/main/java/com/huoran/iasf/controller/SysContentController.java b/src/main/java/com/huoran/iasf/controller/SysContentController.java index d666c59..728d80b 100644 --- a/src/main/java/com/huoran/iasf/controller/SysContentController.java +++ b/src/main/java/com/huoran/iasf/controller/SysContentController.java @@ -144,7 +144,7 @@ public class SysContentController { @PostMapping("/newlyPublishedArticles") @ApiOperation(value = "站点最新发布的文章", response = PageContentReqVO.class) - public R newlyPublishedArticles(@RequestBody @Valid PageContentReqVO content) { + public R newlyPublishedArticles(@Valid @RequestBody PageContentReqVO content) { return service.newlyPublishedArticles(content); } diff --git a/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java index 8b407ab..7f909ca 100644 --- a/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java +++ b/src/main/java/com/huoran/iasf/service/impl/SysColumnServiceImpl.java @@ -1,5 +1,6 @@ package com.huoran.iasf.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -91,6 +92,12 @@ public class SysColumnServiceImpl extends ServiceImpl listWithTreeMenuVisible(PaginationColumnReqVO column) { + + if(column.getRole()==null){ + + }else if (column.getRole()!=null||column.getRole().equals("admin") || ObjectUtil.isNotNull(column.isIsadmin()) || column.isIsadmin()){ + throw new IllegalArgumentException("参数名不能包含admin"); + } //查询所有栏目 List columnList = baseMapper.filterMenuVisible(column); diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java index 248aeda..b7f4356 100644 --- a/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java +++ b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java @@ -1,5 +1,6 @@ package com.huoran.iasf.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -79,6 +80,11 @@ public class SysContentServiceImpl extends ServiceImpl page = new Page(reqVO.getPageNum(), reqVO.getPageSize()); IPage pageList = baseMapper.getPublishedArticles(page, reqVO); return R.success(pageList); diff --git a/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java index 1591e01..c8ec0d5 100644 --- a/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java +++ b/src/main/java/com/huoran/iasf/vo/req/PageContentReqVO.java @@ -1,10 +1,14 @@ package com.huoran.iasf.vo.req; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @描述:文章管理 @@ -49,6 +53,26 @@ public class PageContentReqVO extends PageReqVO { @ApiModelProperty(value = "召开类型(1.即将召开 2.已经召开)") private Integer convokeType; + private String role; + + private boolean isadmin; + + //多余参数处理,参数值不能出现admin,否则返回400 + private Map extraParams = new HashMap<>(); + @JsonAnySetter + public void setExtraParam(String name, String value) { + // 在这里可以对额外参数进行验证或处理 + if (name.contains("admin")||value.contains("admin")) { + throw new IllegalArgumentException("参数名不能包含admin"); + } + this.extraParams.put(name, value); + } + + @JsonAnyGetter + public Map getExtraParams() { + return extraParams; + } + @ApiModelProperty(value = "修改时间排序(0默认倒序 1升序)") private Integer modifiedTimeSort; diff --git a/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java index 193628f..360e8ab 100644 --- a/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java +++ b/src/main/java/com/huoran/iasf/vo/req/PageReqVO.java @@ -1,8 +1,12 @@ package com.huoran.iasf.vo.req; +import com.fasterxml.jackson.annotation.JsonAnySetter; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.HashMap; +import java.util.Map; + /** * @ProjectName: huorantech * @Package: com.huoran.occupationlab.entity.req @@ -21,4 +25,5 @@ public class PageReqVO { @ApiModelProperty(value = "当前页需要显示的数量", name = "pageSize", example = "10", required = true) private Integer pageSize; + } diff --git a/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java b/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java index 43ed613..6844d0b 100644 --- a/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java +++ b/src/main/java/com/huoran/iasf/vo/req/PaginationColumnReqVO.java @@ -1,9 +1,12 @@ package com.huoran.iasf.vo.req; +import com.fasterxml.jackson.annotation.JsonAnySetter; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; +import java.util.HashMap; +import java.util.Map; /** * @ProjectName: huorantech @@ -34,4 +37,8 @@ public class PaginationColumnReqVO extends PageReqVO { @ApiModelProperty(value = "判断是否为排序接口调用(1为排序接口调用 0我栏目管理列表调用)") private Integer isSort; + private String role; + + private boolean isadmin; + }