WebMvcConfiguration.java
package com.fii.cms.web.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import javax.annotation.Nullable;
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Value("${swagger.enable}")
private boolean swaggerEnabled;
@Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (swaggerEnabled) {
registry.addResourceHandler("/doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
/**
* 格式化
*
* @param registry
*/
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
}
/**
* 添加拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
// 添加一个拦截器,检查会话,URL以admin开头的都使用此拦截器
// registry.addInterceptor(sessionInterceptor).addPathPatterns("/admin/**");
}
@Bean
@Nullable
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler threadPoolScheduler = new ThreadPoolTaskScheduler();
threadPoolScheduler.setThreadNamePrefix("SockJS-");
threadPoolScheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
threadPoolScheduler.setRemoveOnCancelPolicy(true);
return threadPoolScheduler;
}
}
aop.AuthVerifyAOP.java
package com.fii.cms.web.aop;
import com.fii.cms.core.annotation.AuthApis;
import com.fii.cms.core.api.ApiAuthVerify;
import com.fii.cms.core.exception.GlobalException;
import com.fii.cms.core.pojo.vo.app.LocalAppResourceInfo;
import com.fii.cms.core.pojo.vo.user.UserInfoVo;
import com.fii.cms.core.pojo.vo.user.UserParam;
import com.fii.cms.core.resultBody.ResultCode;
import com.fii.cms.user.common.AuthenticationFacade;
import org.apache.commons.lang3.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.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Aspect
@Component
public class AuthVerifyAop {
@Value("${oauth.user_cache_key}")
private String userCacheKey;
@Autowired
private AuthenticationFacade facade;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Pointcut("@annotation( com.fii.cms.core.annotation.AuthApis)")
public void doOperation() {
}
@Before("doOperation()&&@annotation(authApis)")
public void before(JoinPoint point, AuthApis authApis) throws GlobalException {
//获取请求路由
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
assert requestAttributes != null;
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String requestURI = request.getRequestURI();
//获取去用户信息
String account = facade.getCurrentUserName();
UserInfoVo userInfoVo = (UserInfoVo) redisTemplate.opsForHash().get(userCacheKey, account);
if (userInfoVo == null)
throw new GlobalException(ResultCode.USER_NOT_LOGIN);
//获取用户本系统权限信息
List<LocalAppResourceInfo> localRes = userInfoVo.getLocalRes();
if (localRes != null && localRes.size() > 0) {
List<String> collect = localRes.stream().map(LocalAppResourceInfo::getResourceId).collect(Collectors.toList());
//通过注解获取被访问接口可允许的权限ID
String[] value = authApis.value();
if (value.length == 0)
//通过路由获取被访问接口可允许的权限ID
value = ApiAuthVerify.getResourceIds(requestURI);
if (value == null || value.length == 0)
throw new GlobalException(ResultCode.PERMISSION_NOT_ALLOW);
//特殊角色权限认证
Object[] args = point.getArgs();
if (!special(args, collect, requestURI))
throw new GlobalException(ResultCode.PERMISSION_NOT_ALLOW);
//权限认证
for (String resource : value) {
if (collect.contains(resource))
return;
}
}
throw new GlobalException(ResultCode.PERMISSION_NOT_ALLOW);
}
private boolean special(Object[] args, List<String> collect, String requestURI) {
//角色编辑接口:接口多用权限处理-根据参数判断接口对应的按钮功能
if (Objects.equals(ApiAuthVerify.SYS_ROLE_ENABLE.getUri(), requestURI)) {
String roleName = Objects.isNull(args[1]) ? "" : (String) args[1];
Integer status = Objects.isNull(args[2]) ? null : (Integer) args[2];
String[] resourceIds = ApiAuthVerify.SYS_ROLE_ENABLE.getResourceIds();
if (!StringUtils.isEmpty(roleName)) {
return collect.contains(resourceIds[0]);
}
if (status == null) {
return collect.contains(resourceIds[1]);
}
}
//用户查询接口多用权限认证
if (Objects.equals(ApiAuthVerify.SYS_USER_M.getUri(), requestURI)) {
UserParam userParams = (UserParam) args[0];
String[] resourceIds = ApiAuthVerify.SYS_USER_M.getResourceIds();
//查询角色用户列表
if (StringUtils.isNotEmpty(userParams.getRoleId())) {
return collect.contains(resourceIds[1]);
} else {
if (StringUtils.isNotEmpty(userParams.getOrganizeId())) {
if (collect.contains(resourceIds[2]))
return true;
else
return collect.contains(resourceIds[0]);
}
return collect.contains(resourceIds[0]);
}
}
return true;
}
}
AuthApis.java
package com.fii.cms.core.annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface AuthApis {
String[] value() default {};
String desc() default "";
}
ApiAuthVerify.java
package com.fii.cms.core.api;
import java.util.Objects;
public enum ApiAuthVerify {
/**用户管理*/
SYS_USER_M("/oauth/user/list", new String[]{"SYS-USER-M","SYS-ROLE-USER","SYS-ORG-USER"}),
SYS_USER_ENABLE("/oauth/user/status", new String[]{"SYS-USER-ENABLE"}),
SYS_USER_EDIT("/oauth/update/user", new String[]{"SYS-USER-EDIT"}),
SYS_USER_RESETPSW("/oauth/reset/password", new String[]{"SYS-USER-RESETPSW"}),
SYS_USER_IMPORT("/oauth/user/upload", new String[]{"SYS-USER-IMPORT"}),
SYS_USER_ADD("/oauth/add/user", new String[]{"SYS-USER-ADD"}),
SYS_USER_CHANGEROLE("/role/add/user/roles", new String[]{"SYS-USER-CHANGEROLE", "SYS-USER-ASSIGNROLE"}),
SYS_USER_CHANGEORGANIZE("/organize/add/user/organizes", new String[]{"SYS-USER-CHANGEORGANIZE"}),
SYS_USER_LOOKAUTH("/auth/user/list", new String[]{"SYS-AUTH-M","SYS-USER-LOOKAUTH"}),
SYS_USER_PERMISSION("/auth/distribution", new String[]{"SYS-AUTH-M","SYS-USER-PERMISSION"}),
/**角色管理*/
SYS_ROLE_M("/role/role/list",new String[]{"SYS-ROLE-M"}),
SYS_ROLE_ADD("/role/add",new String[]{"SYS-ROLE-ADD"}),
SYS_ROLE_DELETE("/role/delete",new String[]{"SYS-ROLE-DELETE"}),
SYS_ROLE_ENABLE("/role/edit",new String[]{"SYS-ROLE-EDIT","SYS-ROLE-ENABLE"}),
SYS_ROLE_ADD_USER("/role/add/role/user",new String[]{"SYS-ROLE-ADD-USER"}),
SYS_ROLE_DELETE_USER("/role/delete/role/user",new String[]{"SYS-ROLE-DELETE-USER"}),
// SYS_ROLE_AUTH("",new String[]{"SYS-ROLE-AUTH"}),
/**组织管理*/
SYS_ORG_M("/organize/list/info",new String[]{"SYS-ORG-M"}),
SYS_ORG_ENABLE("/organize/disable",new String[]{"SYS-ORG-ENABLE"}),
SYS_ORG_EDIT("/organize/edit",new String[]{"SYS-ORG-EDIT"}),
SYS_ORG_DELETE_USER("/organize/delete/users",new String[]{"SYS-ORG-DELETE-USER"}),
SYS_ORG_DELETE("/organize/delete",new String[]{"SYS-ORG-DELETE"}),
SYS_ORG_ADD_USER("/organize/add/users",new String[]{"SYS-ORG-ADD-USER"}),
SYS_ORG_ADD("/organize/add",new String[]{"SYS-ORG-ADD"}),
/**权限管理*/
SYS_AUTH_APP("/auth/app/list",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_ADD("/auth/add/point",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_DELETE("/auth/remove/point",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_EDIT("/auth/edit/point",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_APP_POINTS("/auth/all/point/list",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_POINT_RESOURCE("/auth/point/list",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_ENABLE("/auth/enable/point",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_ROLE_OR_USER("/auth/resource/distribution/list",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_ROLE_OR_USER_POINT("/auth/resource/detail",new String[]{"SYS-ROLE-AUTH","SYS-ROLE-AUTH","SYS-USER-PERMISSION"}),
SYS_AUTH_CANCEL("/auth/user/invalid",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_IMPORT("/auth/auth/upload",new String[]{"SYS-AUTH-M"}),
SYS_AUTH_EXPORT("/auth/auth/download",new String[]{"SYS-AUTH-M"}),
/**权限管理*/
SYS_APP_REGISTER("/client/add/app",new String[]{"SYS-APP-R","SYS-APP-M"}),
SYS_APP_LIST("/client/app/list",new String[]{"SYS-APP-R","SYS-APP-M"}),
SYS_APP_EDIT("/client/app/edit",new String[]{"SYS-APP-R","SYS-APP-M"}),
SYS_APP_DELETE("/client/app/delete",new String[]{"SYS-APP-R","SYS-APP-M"}),
/**消息管理**/
SYS_MESSAGE_HISTORY("/message/history/list",new String[]{"SYS-MESSAGE-HISTORY"})
;
private String uri;
private String[] resourceIds;
ApiAuthVerify(String uri, String[] resourceIds) {
this.uri = uri;
this.resourceIds = resourceIds;
}
public static String[] getResourceIds(String uri) {
for (ApiAuthVerify verify : ApiAuthVerify.values()) {
if (Objects.equals(verify.uri, uri))
return verify.resourceIds;
}
return null;
}
public String getUri() {
return uri;
}
public String[] getResourceIds() {
return resourceIds;
}
}
AuthenticationFacade.java
package com.fii.cms.user.common;
import com.fii.cms.core.exception.GlobalException;
import com.fii.cms.core.resultBody.ResultCode;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.List;
@Component
public class AuthenticationFacade {
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public String getCurrentUserName() {
Object o = getAuthentication().getPrincipal();
String username = "";
if (o instanceof User)
username = ((User) o).getUsername();
if (o instanceof String) {
username = (String) o;
}
return username;
}
public void verifyLogin(){
String currentUserName = getCurrentUserName();
if (StringUtils.isEmpty(currentUserName))
throw new GlobalException(ResultCode.USER_NOT_LOGIN);
}
public boolean verifyAuthen(String role){
List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(role);
return getAuthentication().getAuthorities().contains(grantedAuthorities.get(0));
}
public boolean verifySuperAuthen(){
return verifyAuthen("ROLE_ADMIN");
}
}
OauthController.java
package com.fii.cms.user.controller;
import com.fii.cms.core.annotation.AuthApis;
import com.fii.cms.core.pojo.vo.user.*;
import com.fii.cms.core.resultBody.PageBody;
import com.fii.cms.core.resultBody.ResultBody;
import com.fii.cms.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Api(tags = "oauth用户相关")
@RequestMapping("oauth")
@RestController
public class OauthUserController {
@Autowired
private UserService userService;
@ApiOperation(value = "获取当前用户信息", httpMethod = "GET")
@RequestMapping("/current/user")
public ResultBody<UserInfoVo> getCurrentUserInfo() {
return ResultBody.success(userService.getCurrentUserInfo());
}
@ApiOperation(value = "获取指定用户信息", httpMethod = "GET")
@RequestMapping("/user")
public ResultBody<UserInfoVo> getUserInfo(@ApiParam(value = "用户ID", required = true) @RequestParam String userId) {
return userService.getUserInfo(userId);
}
@ApiOperation(value = "获取简单用户信息", httpMethod = "GET")
@RequestMapping("/user/simple")
public ResultBody<List<UserSimpleInfoVo>> getUserSimpleInfo(@ApiParam(value = "用户工号/姓名") @RequestParam(required = false) String account) {
return userService.getUserSimpleInfo(account);
}
@AuthApis
@ApiOperation(value = "获取用户信息列表", httpMethod = "POST")
@PostMapping("/user/list")
public ResultBody<PageBody<List<UserInfoVo>>> getUserInfoList(@ApiParam(value = "用户信息") @RequestBody(required = false) UserParam userParam) {
return userService.getUserInfoList(userParam);
}
@AuthApis
@ApiOperation(value = "添加用户信息用户信息", httpMethod = "POST")
@PostMapping("/add/user")
public ResultBody addUser(@ApiParam(value = "用户信息") @Validated @RequestBody AddUserVo addUserVo) {
return userService.addUser(addUserVo);
}
@AuthApis
@ApiOperation(value = "修改用户信息用户信息", httpMethod = "POST")
@PostMapping("/update/user")
public ResultBody updateUser(@ApiParam(value = "用户信息") @Validated @RequestBody AddUserVo addUserVo) {
return userService.updateUser(addUserVo);
}
@ApiOperation(value = "修改个人用户信息用户信息", httpMethod = "POST")
@PostMapping("/update/personal")
public ResultBody updatePersonal(@ApiParam(value = "用户信息") @Validated @RequestBody UserPersonalVo addUserVo) {
return userService.updatePersonal(addUserVo);
}
@AuthApis
@ApiOperation(value = "禁用用户", httpMethod = "POST")
@PostMapping("/user/status")
public ResultBody editUserStatus(@ApiParam(value = "用户Id:多个用英文逗号隔开") @RequestParam String userId,
@ApiParam(value = "启用状态:0为启用,1为未启用") @RequestParam Integer status) {
return userService.editUserStatus(userId, status);
}
@AuthApis
@ApiOperation(value = "重置密码", httpMethod = "POST")
@PostMapping("/reset/password")
public ResultBody resetPassword(@ApiParam(value = "用户Id") @RequestParam String userId,
@ApiParam(value = "密码") @RequestParam String password) {
return userService.resetPassword(userId, password);
}
@ApiOperation(value = "修改密码", httpMethod = "POST")
@PostMapping("/edit/password")
public ResultBody editPassword(@ApiParam(value = "用户Id",required = true) @RequestParam String userId,
@ApiParam(value = "旧密码",required = true) @RequestParam String oldPassword,
@ApiParam(value = "新密码",required = true) @RequestParam String newPassword) {
return userService.editPassword(userId, oldPassword, newPassword);
}
// @ApiOperation(value = "发送验证码", httpMethod = "POST")
// @PostMapping("/send/code")
// public ResultBody sendCode(@ApiParam(value = "用户工号") @RequestParam String account,
// HttpServletRequest request) {
// return userService.sendCode(account, request);
// }
@ApiOperation(value = "忘记密码", httpMethod = "POST")
@PostMapping("/forget/password")
public ResultBody forgetPassword(@ApiParam(value = "用户工号") @RequestParam String account,
@ApiParam(value = "验证码") @RequestParam String code,
@ApiParam(value = "新密码") @RequestParam String passwordNew,
HttpServletRequest request) {
return userService.forgetPassword(account, code, passwordNew, request);
}
@ApiOperation(value = "登录", httpMethod = "POST")
@PostMapping("/login")
public ResultBody login() {
return ResultBody.success();
}
@ApiOperation(value = "登出", httpMethod = "GET")
@GetMapping("/logout")
public ResultBody logout(HttpServletRequest request) {
return userService.logout(request);
}
@ApiOperation(value = "服务端登录获取token", httpMethod = "GET")
@GetMapping("get/token")
public ResultBody getToken() {
return ResultBody.success(userService.getToken());
}
// @ApiOperation(value = "使token失效", httpMethod = "GET")
// @GetMapping("/revokeToken")
// public ResultBody revokeToken(HttpServletRequest request) {
// return userService.revokeToken(request);
// }
@ApiOperation(value = "用户导入模板下载", httpMethod = "GET")
@GetMapping("download/template")
public void downloadTemplate(HttpServletResponse response) {
userService.downloadTemplate(response);
}
@AuthApis
@ApiOperation(value = "用户批量上传", httpMethod = "POST")
@PostMapping("user/upload")
public ResultBody userUpload(@RequestParam("file") MultipartFile file) throws IOException {
return userService.userUpload(file);
}
}