소스 검색

vector 完成配置权限

wuweihao 5 년 전
부모
커밋
42ffb9a97d

+ 15 - 0
pom.xml

@@ -87,6 +87,21 @@
         </dependency>
 
 
+        <!-- shiro -->
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+            <version>1.4.0</version>
+        </dependency>
+
+        <!-- jwt -->
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+
+
     </dependencies>
 
     <build>

+ 47 - 47
src/main/java/com/fd/config/MyInterceptor.java

@@ -1,47 +1,47 @@
-package com.fd.config;
-
-import lombok.extern.log4j.Log4j2;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Created by Owen on 2019/10/25 0025 16:49
- *
- *  拦截验证
- */
-@Log4j2
-public class MyInterceptor implements HandlerInterceptor {
-
-    /**
-     * 重写preHandle方法
-     * @param request
-     * @param response
-     * @param handler
-     * @return
-     * @throws Exception
-     */
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-//        log.info("run preHandle");
-//
-//        log.info("request url: {}", request.getRequestURL());
-//        log.info("request tRemoteAddr: {}", request.getRemoteAddr());
-
-
-        String requestHeaders = request.getHeader("Access-Control-Request-Headers");
-        if (requestHeaders==null) {
-            requestHeaders = "";
-        }
-        response.setHeader("Access-Control-Allow-Credentials", "true");
-        response.setHeader("Access-Control-Allow-Methods", "HEAD,PUT,DELETE,POST,GET");
-        response.setHeader("Access-Control-Allow-Headers", "Accept, Origin, XRequestedWith, Content-Type, LastModified," + requestHeaders);
-        response.setHeader("Access-Control-Allow-Origin", "*");
-
-
-        return true;
-    }
-
-
-}
+//package com.fd.config;
+//
+//import lombok.extern.log4j.Log4j2;
+//import org.springframework.web.servlet.HandlerInterceptor;
+//
+//import javax.servlet.http.HttpServletRequest;
+//import javax.servlet.http.HttpServletResponse;
+//
+///**
+// * Created by Owen on 2019/10/25 0025 16:49
+// *
+// *  拦截验证
+// */
+//@Log4j2
+//public class MyInterceptor implements HandlerInterceptor {
+//
+//    /**
+//     * 重写preHandle方法
+//     * @param request
+//     * @param response
+//     * @param handler
+//     * @return
+//     * @throws Exception
+//     */
+//    @Override
+//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+////        log.info("run preHandle");
+////
+////        log.info("request url: {}", request.getRequestURL());
+////        log.info("request tRemoteAddr: {}", request.getRemoteAddr());
+//
+//
+//        String requestHeaders = request.getHeader("Access-Control-Request-Headers");
+//        if (requestHeaders==null) {
+//            requestHeaders = "";
+//        }
+//        response.setHeader("Access-Control-Allow-Credentials", "true");
+//        response.setHeader("Access-Control-Allow-Methods", "HEAD,PUT,DELETE,POST,GET");
+//        response.setHeader("Access-Control-Allow-Headers", "Accept, Origin, XRequestedWith, Content-Type, LastModified," + requestHeaders);
+//        response.setHeader("Access-Control-Allow-Origin", "*");
+//
+//
+//        return true;
+//    }
+//
+//
+//}

+ 115 - 115
src/main/java/com/fd/config/WebMvcConfg.java

@@ -1,115 +1,115 @@
-package com.fd.config;
-
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import com.alibaba.fastjson.serializer.ToStringSerializer;
-import com.alibaba.fastjson.support.config.FastJsonConfig;
-import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
-import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.MediaType;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Created by Owen on 2019/10/25 0025 16:29
- */
-@Configuration
-public class WebMvcConfg implements WebMvcConfigurer {
-
-
-    @Bean
-    public MyInterceptor myInterceptor(){
-        return new MyInterceptor();
-    }
-
-    /**
-   * 重写addInterceptors方法
-   * addPathPatterns:需要拦截的访问路径
-   * excludePathPatterns:不需要拦截的路径,
-   * String数组类型可以写多个用","分割
-   */
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        registry.addInterceptor(myInterceptor())
-//                .addPathPatterns("/**")
-                .addPathPatterns("/api/**")
-                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html");
-    }
-
-    /**
-     * 配置全局跨域
-     */
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**")
-                .allowedOrigins("*")
-                .allowCredentials(true)
-                .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
-                .maxAge(3600);
-    }
-
-
-
-
-
-    /**
-     * fastJson相关设置
-     * Dto包含json,需要配置不然会异常
-     * @return
-     */
-    @Bean
-    public HttpMessageConverters customConverters() {
-
-
-        FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();
-
-        // 创建FastJson信息转换对象
-        FastJsonConfig fastJsonConfig = new FastJsonConfig();
-
-        /**
-         * 创建FastJsonConfig对象并设定序列化规则  序列化规则详见SerializerFeature类中
-         *
-         * 加入 fastJsonConfig.setSerializerFeatures 这方法,swagger会受影响。
-         * 目前把他注释掉,也能正常访问发送强求,先用着
-         * fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteNonStringValueAsString);
-         */
-
-        // 设置全程返回时间
-        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
-        // 设置返回值为null是时输出,不写的话,null 字段 不返回。也可以设置返回空串
-//        fastJsonConfig.setSerializerFeatures(SerializerFeature.IgnoreNonFieldGetter);
-//        fastJsonConfig.setSerializerFeatures(SerializerFeature.NotWriteDefaultValue);
-        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
-//        fastJsonConfig.setSerializerFeatures(SerializerFeature.NotWriteDefaultValue, SerializerFeature.IgnoreNonFieldGetter);
-        fastJson.setFastJsonConfig(fastJsonConfig);
-
-        //3、中文乱码解决方案
-        List<MediaType> mediaTypeList = new ArrayList<>();
-        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
-        mediaTypeList.add(MediaType.valueOf("text/html;charset=UTF-8"));
-
-
-        //4、将转换规则应用于转换对象
-        fastJson.setSupportedMediaTypes(mediaTypeList);
-
-
-        return new HttpMessageConverters(fastJson);
-    }
-
-
-
-
-
-
-
-
-
-}
+//package com.fd.config;
+//
+//import com.alibaba.fastjson.serializer.SerializerFeature;
+//import com.alibaba.fastjson.serializer.ToStringSerializer;
+//import com.alibaba.fastjson.support.config.FastJsonConfig;
+//import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.module.SimpleModule;
+//import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
+//import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.http.MediaType;
+//import org.springframework.web.servlet.config.annotation.CorsRegistry;
+//import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+///**
+// * Created by Owen on 2019/10/25 0025 16:29
+// */
+//@Configuration
+//public class WebMvcConfg implements WebMvcConfigurer {
+//
+//
+//    @Bean
+//    public MyInterceptor myInterceptor(){
+//        return new MyInterceptor();
+//    }
+//
+//    /**
+//   * 重写addInterceptors方法
+//   * addPathPatterns:需要拦截的访问路径
+//   * excludePathPatterns:不需要拦截的路径,
+//   * String数组类型可以写多个用","分割
+//   */
+//    @Override
+//    public void addInterceptors(InterceptorRegistry registry) {
+//        registry.addInterceptor(myInterceptor())
+////                .addPathPatterns("/**")
+//                .addPathPatterns("/api/**")
+//                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html");
+//    }
+//
+//    /**
+//     * 配置全局跨域
+//     */
+//    @Override
+//    public void addCorsMappings(CorsRegistry registry) {
+//        registry.addMapping("/**")
+//                .allowedOrigins("*")
+//                .allowCredentials(true)
+//                .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
+//                .maxAge(3600);
+//    }
+//
+//
+//
+//
+//
+//    /**
+//     * fastJson相关设置
+//     * Dto包含json,需要配置不然会异常
+//     * @return
+//     */
+//    @Bean
+//    public HttpMessageConverters customConverters() {
+//
+//
+//        FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();
+//
+//        // 创建FastJson信息转换对象
+//        FastJsonConfig fastJsonConfig = new FastJsonConfig();
+//
+//        /**
+//         * 创建FastJsonConfig对象并设定序列化规则  序列化规则详见SerializerFeature类中
+//         *
+//         * 加入 fastJsonConfig.setSerializerFeatures 这方法,swagger会受影响。
+//         * 目前把他注释掉,也能正常访问发送强求,先用着
+//         * fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteNonStringValueAsString);
+//         */
+//
+//        // 设置全程返回时间
+//        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
+//        // 设置返回值为null是时输出,不写的话,null 字段 不返回。也可以设置返回空串
+////        fastJsonConfig.setSerializerFeatures(SerializerFeature.IgnoreNonFieldGetter);
+////        fastJsonConfig.setSerializerFeatures(SerializerFeature.NotWriteDefaultValue);
+//        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
+////        fastJsonConfig.setSerializerFeatures(SerializerFeature.NotWriteDefaultValue, SerializerFeature.IgnoreNonFieldGetter);
+//        fastJson.setFastJsonConfig(fastJsonConfig);
+//
+//        //3、中文乱码解决方案
+//        List<MediaType> mediaTypeList = new ArrayList<>();
+//        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
+//        mediaTypeList.add(MediaType.valueOf("text/html;charset=UTF-8"));
+//
+//
+//        //4、将转换规则应用于转换对象
+//        fastJson.setSupportedMediaTypes(mediaTypeList);
+//
+//
+//        return new HttpMessageConverters(fastJson);
+//    }
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 14 - 13
src/main/java/com/fd/constant/Command.java


+ 2 - 0
src/main/java/com/fd/constant/MsgCode.java

@@ -44,6 +44,8 @@ public class MsgCode {
 
     public static final String E52000 = "入队操作失败,请稍后再试";
 
+    public static final String U53000 = "用户不存在";
+
 
 
 

+ 32 - 0
src/main/java/com/fd/constant/UserCode.java

@@ -0,0 +1,32 @@
+package com.fd.constant;
+
+/**
+ * Created by Owen on 2019/12/18 0018 16:03
+ *
+ * 用户相关
+ */
+public class UserCode {
+
+    /**
+     * 管理员角色
+     */
+    public static final String USER_ROLE_ADMIN = "admin";
+
+    /**
+     * 部门经理角色
+     */
+    public static final String USER_ROLE_ROOT = "root";
+
+    /**
+     * 普通用户角色
+     */
+    public static final String USER_ROLE_USER = "user";
+
+
+    /**
+     * 用户组别
+     */
+    public static final String USER_GROUP_A = "A";
+
+    public static final String USER_GROUP_B = "B";
+}

+ 52 - 0
src/main/java/com/fd/controller/ExceptionController.java

@@ -0,0 +1,52 @@
+package com.fd.controller;
+
+import com.fd.util.R;
+import org.apache.shiro.ShiroException;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 统一捕捉异常,自定义返回参数
+ */
+@RestControllerAdvice
+public class ExceptionController {
+
+    // 捕捉shiro的异常
+    @ResponseStatus(HttpStatus.UNAUTHORIZED)
+    @ExceptionHandler(ShiroException.class)
+    public R handle401(ShiroException e) {
+        return new R(401, e.getMessage());
+    }
+
+    // 捕捉UnauthorizedException
+    @ResponseStatus(HttpStatus.UNAUTHORIZED)
+    @ExceptionHandler(UnauthorizedException.class)
+    public R handle401() {
+        return new R(401, "Unauthorized");
+    }
+
+    // 捕捉其他所有异常
+    @ExceptionHandler(Exception.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public R globalException(HttpServletRequest request, Throwable ex) {
+        return new R(getStatus(request).value(), ex.getMessage());
+    }
+
+
+
+
+
+    private HttpStatus getStatus(HttpServletRequest request) {
+        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
+        if (statusCode == null) {
+            return HttpStatus.INTERNAL_SERVER_ERROR;
+        }
+        return HttpStatus.valueOf(statusCode);
+    }
+}
+

+ 145 - 0
src/main/java/com/fd/controller/LoginController.java

@@ -0,0 +1,145 @@
+package com.fd.controller;
+
+import com.fd.constant.MsgCode;
+import com.fd.entity.User;
+import com.fd.repository.UserRepository;
+import com.fd.shiro.JWTUtil;
+import com.fd.util.R;
+import lombok.extern.log4j.Log4j2;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Created by Owen on 2019/11/11 0011 16:50
+ */
+@Log4j2
+@RestController
+public class LoginController {
+
+    @Autowired
+    private UserRepository userRepository;
+
+    @PostMapping("/login")
+    public R login(@RequestParam("username") String username,
+                   @RequestParam("password") String password) {
+        log.info("run login , username:{}, password:{}", username, password);
+        User user = userRepository.findByUsername(username);
+        if (user == null) {
+            return new R(53000, MsgCode.U53000);
+        }
+        if (!password.equals(user.getPassword())) {
+            // 密码不相等
+            throw new UnauthorizedException();
+        }
+        return new R(200, JWTUtil.sign(username, password));
+    }
+
+    /**
+     * 所用用户都可以查看,但登陆跟不登录看到的东西不一样
+     *
+     * 用postman 模拟请求头,Authorization
+     */
+    @GetMapping("free")
+    private R free(){
+        log.info("run free");
+
+        Subject subject = SecurityUtils.getSubject();
+        if (!subject.isAuthenticated()) {
+            log.info("没有登录, 游客模式………………");
+            return new R(200, "没有登录, 游客模式………………");
+        }
+
+        log.info("已经登录, 登录模式………………");
+        return new R(200, "已经登录, 登录模式………………");
+
+    }
+
+    @GetMapping("free1")
+    private R free1(HttpServletRequest req){
+        log.info("run free");
+        String authorization = req.getHeader("Authorization");
+        log.info("TOKEN: {}", authorization);
+//        Subject subject = SecurityUtils.getSubject();
+//        if (!subject.isAuthenticated()) {
+//            log.info("没有登录, 游客模式………………");
+//            return new R(200, "没有登录, 游客模式………………");
+//        }
+
+        log.info("已经登录, 登录模式………………");
+        return new R(200, "已经登录, 登录模式………………");
+
+    }
+
+    /**
+     * 只用登录用户才能访问
+     */
+    @GetMapping("/auth/a")
+    @RequiresAuthentication
+    public R requireAuth() {
+        log.info("run requireAuth");
+        userRepository.findAll();
+        log.info("end requireAuth");
+        return new R(200, "已经登录, 登录模式………………");
+    }
+
+    @GetMapping("/auth/k")
+    @RequiresAuthentication
+    public R list() {
+        log.info("run test list");
+        userRepository.findAll();
+        log.info("end test list");
+        return new R(200, "111");
+    }
+
+    /**
+     * 需要登录
+     * 只有admin角色可以看
+     */
+    @GetMapping("/auth/role")
+    @RequiresRoles("admin")
+    public R requireRole() {
+        return new R(200, "只有admin 可以访问");
+    }
+
+
+    /**
+     * 需要登录
+     * 需要有view和edit 权限才可以看
+     */
+    @GetMapping("/auth/edit")
+    @RequiresPermissions(logical = Logical.AND, value = {"view", "edit"})
+    public R requirePermission() {
+        return new R(200, "你拥有view、 edit的权限");
+    }
+
+    /**
+     * 需要登录
+     * 只要有view 权限都可以看
+     */
+    @GetMapping("/auth/view")
+    @RequiresPermissions(logical = Logical.AND, value = {"view"})
+    public R requirePermissionView() {
+        return new R(200, "你拥有view的权限");
+    }
+
+
+    @RequestMapping(path = "/401")
+    @ResponseStatus(HttpStatus.UNAUTHORIZED)
+    public R unauthorized() {
+        return new R(401, "Unauthorized");
+    }
+
+
+
+
+}

+ 14 - 7
src/main/java/com/fd/controller/ModelController.java

@@ -15,6 +15,8 @@ import com.fd.util.RegexUtils;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
@@ -65,7 +67,7 @@ public class ModelController {
 
     @ApiOperation("上传数据,校验文件名")
     @GetMapping("check/{fileName}/")
-    private R checkFileName(@PathVariable("fileName") String fileName) {
+    public R checkFileName(@PathVariable("fileName") String fileName) {
         log.info("run checkFileName {}", fileName);
 
 
@@ -88,7 +90,7 @@ public class ModelController {
 
     @ApiOperation("上传3D模型数据,只能上传zip文件")
     @PostMapping(value = "upload", consumes = {"multipart/form-data"})
-    private R upload(@RequestParam("file") MultipartFile file) {
+    public R upload(@RequestParam("file") MultipartFile file) {
         log.info("run upload");
 
 
@@ -115,7 +117,7 @@ public class ModelController {
 
     @ApiOperation("解压zip文件")
     @GetMapping("unzip/{fileId}/")
-    private R fileUnzip(@PathVariable("fileId") Long fileId) {
+    public R fileUnzip(@PathVariable("fileId") Long fileId) {
         log.info("run fileUnzip: {}", fileId);
 
         OutputFileEntity entity = modelServer.findById(fileId);
@@ -141,16 +143,21 @@ public class ModelController {
         return new R(200, entity);
     }
 
+//    @RequiresAuthentication
+//    @RequiresRoles("admin")
     @ApiOperation("获取3D模型数据列表")
     @PostMapping(value = "list")
-    private R list(@RequestBody PageDto param) {
+//    @RequiresAuthentication
+    public R list(@RequestBody PageDto param) {
+        log.warn("run list");
+        System.out.println("11111111111");
         return modelServer.findByType(TypeCode.FILE_TYPE_MODEL, param);
     }
 
 
     @ApiOperation("删除文件")
     @GetMapping("delete/{fileId}/")
-    private R deleteFile(@PathVariable("fileId") Long fileId) {
+    public R deleteFile(@PathVariable("fileId") Long fileId) {
         log.info("run deleteFile: {}", fileId);
         OutputFileEntity entity = modelServer.findById(fileId);
         entity.setResStatus(1);
@@ -167,7 +174,7 @@ public class ModelController {
 
     @ApiOperation("倾斜摄影数据切片")
     @GetMapping("command/osgb/{fileId}/")
-    private R cmdModelSlice(@PathVariable("fileId") Long fileId) {
+    public R cmdModelSlice(@PathVariable("fileId") Long fileId) {
         log.info("run cmdModelSlice: {}", fileId);
         OutputFileEntity entity = modelServer.findById(fileId);
 
@@ -214,7 +221,7 @@ public class ModelController {
 
     @ApiOperation("移动数据到服务器上")
     @PostMapping("move/{fileId}/")
-    private R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
+    public R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
         log.info("run moveFile: {}", fileId);
         return modelServer.moveFileToServer(fileId, param);
     }

+ 8 - 8
src/main/java/com/fd/controller/RasterController.java

@@ -67,7 +67,7 @@ public class RasterController {
 
     @ApiOperation("上传数据,校验文件名")
     @GetMapping("check/{fileName}/")
-    private R checkFileName(@PathVariable("fileName") String fileName) {
+    public R checkFileName(@PathVariable("fileName") String fileName) {
         log.info("run checkFileName: {}",fileName);
 
 
@@ -94,7 +94,7 @@ public class RasterController {
 
     @ApiOperation("上传栅格数据,只能上传tif文件")
     @PostMapping(value = "upload", consumes = { "multipart/form-data" })
-    private R upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "coord",required = false) String[] coord){
+    public R upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "coord",required = false) String[] coord){
         log.info("run upload");
         log.info("coord: {}", Arrays.toString(coord));
         String strCoord = Arrays.toString(coord);
@@ -166,7 +166,7 @@ public class RasterController {
 
     @ApiOperation("获取栅格数据列表")
     @PostMapping(value = "list")
-    private R list(@RequestBody PageDto param){
+    public R list(@RequestBody PageDto param){
         return rasterServer.findByType(TypeCode.FILE_TYPE_RASTER, param);
     }
 
@@ -174,7 +174,7 @@ public class RasterController {
 
     @ApiOperation("删除文件")
     @GetMapping("delete/{fileId}/")
-    private R deleteFile(@PathVariable("fileId") Long fileId) {
+    public R deleteFile(@PathVariable("fileId") Long fileId) {
         log.info("run deleteFile: {}", fileId);
 
         OutputFileEntity entity = rasterServer.findById(fileId);
@@ -197,7 +197,7 @@ public class RasterController {
 
     @ApiOperation("栅格数据判断坐标")
     @GetMapping("command/judge/coord/{fileId}/")
-    private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
+    public R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
         log.info("run cmdJudgeCoord: {}", fileId);
 
 
@@ -239,7 +239,7 @@ public class RasterController {
 
     @ApiOperation("栅格数据切片命令")
     @GetMapping("command/osgeo/{fileId}/{layerMin}/{layerMax}/")
-    private R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
+    public R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
         log.info("run cmdSlice: {}", fileId);
 
         if (!RegexUtils.regexInt(layerMin)){
@@ -300,7 +300,7 @@ public class RasterController {
 
     @ApiOperation("栅格数据进度查询")
     @GetMapping("progress/{fileId}/")
-    private R getProgress(@PathVariable("fileId") Long fileId) {
+    public R getProgress(@PathVariable("fileId") Long fileId) {
         OutputFileEntity entity = rasterServer.findById(fileId);
         return new R(200, entity);
     }
@@ -308,7 +308,7 @@ public class RasterController {
 
     @ApiOperation("移动数据到服务器上")
     @PostMapping("move/{fileId}/")
-    private R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
+    public R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
         log.info("run moveFile: {}", fileId);
         return rasterServer.moveFileToServer(fileId, param);
     }

+ 22 - 14
src/main/java/com/fd/controller/VectorController.java

@@ -10,6 +10,7 @@ import com.fd.entity.FileEntity;
 import com.fd.entity.OutputFileEntity;
 import com.fd.entity.StyleEntity;
 import com.fd.server.VectorServer;
+import com.fd.shiro.JWTUtil;
 import com.fd.thread.AsyncTask;
 import com.fd.util.FileUtils;
 import com.fd.util.R;
@@ -19,9 +20,11 @@ import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
 import java.io.File;
 import java.util.Arrays;
 import java.util.Date;
@@ -92,12 +95,14 @@ public class VectorController {
 
     @ApiOperation("上传矢量数据, coord:坐标(可以为空), 坐标格式:0,0,0,0,0,0,0")
     @PostMapping(value = "uploadMult/{directoryName}", consumes = {"multipart/form-data"})
-    private R uploadMult(@RequestParam("file") MultipartFile[] file,
+    public R uploadMult(@RequestParam("file") MultipartFile[] file,
                          @PathVariable("directoryName") String directoryName,
-                         @RequestParam(value = "coord", required = false) String[] coord) {
+                         @RequestParam(value = "coord", required = false) String[] coord, HttpServletRequest req) {
         log.info("run uploadMult");
         log.info("coord: {}", Arrays.toString(coord));
 
+        String token = req.getHeader("Authorization");
+
         // 文件是否包含中文字符
         if (RegexUtils.regexChinese(directoryName)) {
             return new R(51005, MsgCode.E51005);
@@ -109,7 +114,7 @@ public class VectorController {
 
         String strCoord = Arrays.toString(coord);
 
-        R r = vectorServer.uploadDirectoryFileMul(file, directoryName, strCoord);
+        R r = vectorServer.uploadDirectoryFileMul(file, directoryName, strCoord, token);
 
         // 判断文件是否有错误
         if (r.getStatus() != 200) {
@@ -183,8 +188,11 @@ public class VectorController {
 
     @ApiOperation("获取矢量数据列表")
     @PostMapping(value = "list")
-    private R list(@RequestBody PageDto param) {
-        return vectorServer.findByType(TypeCode.FILE_TYPE_VECTOR, param);
+    public R list(@RequestBody PageDto param, HttpServletRequest req) {
+        String token = req.getHeader("Authorization");
+//        return vectorServer.findByType(TypeCode.FILE_TYPE_VECTOR, param);
+        Page<OutputFileEntity> list = vectorServer.findByList(param, token);
+        return new R(200, list);
     }
 
 
@@ -195,7 +203,7 @@ public class VectorController {
      */
     @ApiOperation("删除文件")
     @GetMapping("delete/{fileId}/")
-    private R deleteFile(@PathVariable("fileId") Long fileId) {
+    public R deleteFile(@PathVariable("fileId") Long fileId) {
         log.info("run deleteFile: {}", fileId);
         OutputFileEntity entity = vectorServer.findById(fileId);
         entity.setResStatus(1);
@@ -216,7 +224,7 @@ public class VectorController {
 
     @ApiOperation("矢量数据判断坐标")
     @GetMapping("command/judge/coord/{fileId}/")
-    private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
+    public R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
         log.info("run cmdJudgeCoord: {}", fileId);
 
         OutputFileEntity entity = vectorServer.findById(fileId);
@@ -263,12 +271,12 @@ public class VectorController {
 
     @ApiOperation("矢量数据转geojson")
     @GetMapping("command/geojson/{fileId}/")
-    private R cmdGeojson(@PathVariable("fileId") Long fileId) {
+    public R cmdGeojson(@PathVariable("fileId") Long fileId) {
         log.info("run cmdGeojson: {}", fileId);
         OutputFileEntity entity = vectorServer.findById(fileId);
 
         String fileName = StringUtils.substringBefore(entity.getFileName(), ".");
-//        // 截取目录名称
+        // 截取目录名称
         log.info("json path: {}", OUTPUT_FILE_PATH);
         String outPath = OUTPUT_FILE_PATH + "geojson" + File.separator + entity.getDirectory();
         FileUtils.createDir(outPath);
@@ -300,7 +308,7 @@ public class VectorController {
 
     @ApiOperation("矢量数据切片")
     @GetMapping("command/slice/{fileId}/{layerMin}/{layerMax}/")
-    private R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
+    public R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
         log.info("run cmdSlice: {}", fileId);
 
 
@@ -355,14 +363,14 @@ public class VectorController {
 
     @ApiOperation("矢量数据进度查询")
     @GetMapping("progress/{fileId}/")
-    private R getProgress(@PathVariable("fileId") Long fileId) {
+    public R getProgress(@PathVariable("fileId") Long fileId) {
         OutputFileEntity entity = vectorServer.findById(fileId);
         return new R(200, entity);
     }
 
     @ApiOperation("移动数据到服务器上")
     @PostMapping("move/{fileId}/")
-    private R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
+    public R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
         log.info("run moveFile: {}", fileId);
         return vectorServer.moveFileToServer(fileId, param);
     }
@@ -371,14 +379,14 @@ public class VectorController {
 
     @ApiOperation("保存样式")
     @PostMapping("style/save/")
-    private R saveStyle(@RequestBody StyleDto param) {
+    public R saveStyle(@RequestBody StyleDto param) {
         log.info("run saveStyle");
         return vectorServer.editStyle(param);
     }
 
     @ApiOperation("获取样式")
     @GetMapping("style/get/{fileId}/")
-    private R getStyle(@PathVariable("fileId") Long fileId) {
+    public R getStyle(@PathVariable("fileId") Long fileId) {
         log.info("run getStyle: {}", fileId);
         return vectorServer.getStyle(fileId);
     }

+ 12 - 0
src/main/java/com/fd/entity/OutputFileEntity.java

@@ -102,4 +102,16 @@ public class OutputFileEntity extends BaseEntity implements Serializable {
     @Column
     private String servicePath;
 
+    /**
+     * 用户id
+     */
+    @Column
+    private Long userId;
+
+    /**
+     * 用户组别
+     */
+    @Column
+    private String userGroup;
+
 }

+ 33 - 0
src/main/java/com/fd/entity/User.java

@@ -0,0 +1,33 @@
+package com.fd.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+/**
+ * Created by Owen on 2019/11/13 0013 14:57
+ */
+@Data
+@Entity
+@Table(name = "t_user")
+public class User extends BaseEntity implements Serializable {
+
+    @Column
+    private String username;
+
+    @Column
+    private String password;
+
+    @Column
+    private String role;
+
+    @Column
+    private String permission;
+
+    /**
+     * 组别
+     */
+    @Column
+    private String userGroup;
+}

+ 20 - 0
src/main/java/com/fd/repository/OutputFileRepository.java

@@ -24,5 +24,25 @@ public interface OutputFileRepository extends JpaRepository<OutputFileEntity, Lo
     @Query(value = "select r from OutputFileEntity r where r.type=?1 or r.type =?2")
     Page<OutputFileEntity> findByType(String type, String type1, Pageable pageable);
 
+    /**
+     * 根据用户组查询
+     * @param type
+     * @param pageable
+     * @param userGroup
+     * @return
+     */
+    @Query(value = "select r from OutputFileEntity r where r.resStatus = 0 and r.type=?1 and r.userGroup =?2")
+    Page<OutputFileEntity> findByTypeAndUserGroup(String type, String userGroup, Pageable pageable);
+
+
+    /**
+     * 根据用户id组查询
+     * @param type
+     * @param pageable
+     * @return
+     */
+    @Query(value = "select r from OutputFileEntity r where r.resStatus = 0 and r.type=?1 and r.userId =?2")
+    Page<OutputFileEntity> findByTypeAndUserId(String type, Long userId, Pageable pageable);
+
 
 }

+ 14 - 0
src/main/java/com/fd/repository/UserRepository.java

@@ -0,0 +1,14 @@
+package com.fd.repository;
+
+import com.fd.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * Created by Owen on 2019/10/28 0028 11:36
+ *
+ * JpaSpecificationExecutor 条件分页查询
+ */
+public interface UserRepository extends JpaRepository<User, Long> {
+
+    User findByUsername(String username);
+}

+ 10 - 1
src/main/java/com/fd/server/VectorServer.java

@@ -7,6 +7,7 @@ import com.fd.entity.FileEntity;
 import com.fd.entity.OutputFileEntity;
 import com.fd.entity.StyleEntity;
 import com.fd.util.R;
+import org.springframework.data.domain.Page;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
@@ -19,7 +20,7 @@ public interface VectorServer {
 
 //    R uploadDirectoryFile(MultipartFile file, String directoryName, String coord);
 
-    R uploadDirectoryFileMul(MultipartFile [] file, String directoryName, String coord);
+    R uploadDirectoryFileMul(MultipartFile[] file, String directoryName, String coord, String token);
 
     R findByType(String fileTypeVector, PageDto param);
 
@@ -75,4 +76,12 @@ public interface VectorServer {
     FileEntity saveInputFile(FileEntity fileEntity);
 
     Integer exeCmd(String cmd);
+
+    /**
+     * 根据用户权限查询
+     * @param param
+     * @param token
+     * @return
+     */
+    Page<OutputFileEntity> findByList(PageDto param, String token);
 }

+ 58 - 6
src/main/java/com/fd/server/impl/VectorServerImpl.java

@@ -3,20 +3,22 @@ package com.fd.server.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.fd.constant.Command;
 import com.fd.constant.MsgCode;
 import com.fd.constant.TypeCode;
+import com.fd.constant.UserCode;
 import com.fd.dto.ConfigJsonDto;
 import com.fd.dto.PageDto;
 import com.fd.dto.StyleDto;
 import com.fd.entity.FileEntity;
 import com.fd.entity.OutputFileEntity;
 import com.fd.entity.StyleEntity;
+import com.fd.entity.User;
 import com.fd.repository.FileRepository;
 import com.fd.repository.OutputFileRepository;
 import com.fd.repository.StyleRepository;
-import com.fd.server.CmdServer;
+import com.fd.repository.UserRepository;
 import com.fd.server.VectorServer;
+import com.fd.shiro.JWTUtil;
 import com.fd.util.FileUtils;
 import com.fd.util.R;
 import com.fd.util.RegexUtils;
@@ -73,10 +75,11 @@ public class VectorServerImpl implements VectorServer {
     private OutputFileRepository outputFileRepository;
 
     @Autowired
-    private CmdServer cmdServer;
+    private StyleRepository styleRepository;
 
     @Autowired
-    private StyleRepository styleRepository;
+    private UserRepository userRepository;
+
 
 
     @Override
@@ -195,13 +198,12 @@ public class VectorServerImpl implements VectorServer {
 
 
     @Override
-    public R uploadDirectoryFileMul(MultipartFile[] files, String directoryName, String coord) {
+    public R uploadDirectoryFileMul(MultipartFile[] files, String directoryName, String coord, String token) {
 
         log.warn("run uploadDirectoryFileMul");
 
 
         // 判断目录重名
-//        List<FileEntity> en = fileRepository.findByDirectory(directoryName);
         List<FileEntity> en = fileRepository.findByDirectoryAndResStatus(directoryName, 0);
 
         if (en.size() > 0) {
@@ -277,6 +279,11 @@ public class VectorServerImpl implements VectorServer {
             return new R(51008, MsgCode.E51008);
         }
 
+        String username = JWTUtil.getUsername(token);
+
+        // 根据用户名查找用户
+        User user = userRepository.findByUsername(username);
+
         OutputFileEntity outputFile = new OutputFileEntity();
         if (shpFlag) {
             entity.setDirectory(directoryName);
@@ -299,6 +306,10 @@ public class VectorServerImpl implements VectorServer {
             outputFile.setCreateTime(new Date());
             outputFile.setUpdateTime(new Date());
             outputFile.setResStatus(0);
+
+            // 添加分组
+            outputFile.setUserId(user.getId());
+            outputFile.setUserGroup(user.getUserGroup());
             outputFile = outputFileRepository.save(outputFile);
         }
         return new R(200, outputFile);
@@ -310,6 +321,11 @@ public class VectorServerImpl implements VectorServer {
         return new R(200, page);
     }
 
+//    @Override
+//    public R findByTypeAndUser(String fileTypeVector, PageDto param, String userName) {
+//        return null;
+//    }
+
 
     @Override
     public List<FileEntity> findByDirectory(String directory) {
@@ -562,6 +578,42 @@ public class VectorServerImpl implements VectorServer {
         return isCmd;
     }
 
+    /**
+     * 根据用户查询
+     * @param param
+     * @param token
+     * @return
+     */
+    @Override
+    public Page<OutputFileEntity> findByList(PageDto param, String token) {
+
+        String username = JWTUtil.getUsername(token);
+
+        // 根据用户名查找用户
+        User user = userRepository.findByUsername(username);
+
+        // 判断用户角色
+
+        Page<OutputFileEntity> page = null;
+
+        // 部门经理
+        if (UserCode.USER_ROLE_ROOT.equals(user.getRole())) {
+            page = outputFileRepository.findByTypeAndUserGroup(TypeCode.FILE_TYPE_VECTOR, user.getUserGroup(), PageRequest.of(param.getPageNum(), param.getPageSize(), Sort.by("createTime").descending()));
+
+            //普通用户
+        } else if (UserCode.USER_ROLE_USER.equals(user.getRole())) {
+            page = outputFileRepository.findByTypeAndUserId(TypeCode.FILE_TYPE_VECTOR, user.getId(), PageRequest.of(param.getPageNum(), param.getPageSize(), Sort.by("createTime").descending()));
+
+            // 管理员用户
+        } else {
+            page = outputFileRepository.findByTypeAndResStatus(TypeCode.FILE_TYPE_VECTOR, 0, PageRequest.of(param.getPageNum(), param.getPageSize(), Sort.by("createTime").descending()));
+
+        }
+
+
+        return page;
+    }
+
     private Integer exeCmdSingle(String commandStr) {
 
         // 命令运行结果 1:失败, 0:成功

+ 104 - 0
src/main/java/com/fd/shiro/JWTFilter.java

@@ -0,0 +1,104 @@
+package com.fd.shiro;
+
+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+/**
+ * 自定义拦截规则
+ */
+public class JWTFilter extends BasicHttpAuthenticationFilter {
+
+    private Logger LOGGER = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 判断用户是否想要登入。
+     * 检测header里面是否包含Authorization字段即可
+     */
+    @Override
+    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
+        HttpServletRequest req = (HttpServletRequest) request;
+        String authorization = req.getHeader("Authorization");
+        return authorization != null;
+    }
+
+    /**
+     *
+     */
+    @Override
+    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        String authorization = httpServletRequest.getHeader("Authorization");
+        JWTToken token = new JWTToken(authorization);
+        // 提交给realm进行登入,如果错误他会抛出异常并被捕获
+        getSubject(request, response).login(token);
+        // 如果没有抛出异常则代表登入成功,返回true
+        return true;
+    }
+
+    /**
+     * 这里我们详细说明下为什么最终返回的都是true,即允许访问
+     * 例如我们提供一个地址 GET /article
+     * 登入用户和游客看到的内容是不同的
+     * 如果在这里返回了false,请求会被直接拦截,用户看不到任何东西
+     * 所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入
+     * 如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可
+     * 但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大
+     *
+     * owen:
+     *  return false ,表示全局拦截,必须登录才可以访问接口,除非配置了免拦截
+     *  "" @RequiresAuthentication 现在不需要配置这个注解来免登录
+     *
+     */
+    @Override
+    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+        if (isLoginAttempt(request, response)) {
+            try {
+                executeLogin(request, response);
+                return true;
+            } catch (Exception e) {
+                response401(request, response);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 对跨域提供支持
+     */
+    @Override
+    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
+        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
+        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
+        // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
+        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
+            httpServletResponse.setStatus(HttpStatus.OK.value());
+            return false;
+        }
+        return super.preHandle(request, response);
+    }
+
+    /**
+     * 将非法请求跳转到 /401
+     */
+    private void response401(ServletRequest req, ServletResponse resp) {
+        try {
+            HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
+            httpServletResponse.sendRedirect("/401");
+        } catch (IOException e) {
+            LOGGER.error(e.getMessage());
+        }
+    }
+}

+ 23 - 0
src/main/java/com/fd/shiro/JWTToken.java

@@ -0,0 +1,23 @@
+package com.fd.shiro;
+
+import org.apache.shiro.authc.AuthenticationToken;
+
+public class JWTToken implements AuthenticationToken {
+
+    // 密钥
+    private String token;
+
+    public JWTToken(String token) {
+        this.token = token;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return token;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return token;
+    }
+}

+ 74 - 0
src/main/java/com/fd/shiro/JWTUtil.java

@@ -0,0 +1,74 @@
+package com.fd.shiro;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTDecodeException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+
+@Log4j2
+public class JWTUtil {
+
+    // 过期时间30分钟
+    private static final long EXPIRE_TIME = 30*60*1000;
+
+
+    /**
+     * 校验token是否正确
+     * @param token 密钥
+     * @param secret 用户的密码
+     * @return 是否正确
+     */
+    public static boolean verify(String token, String username, String secret) {
+        try {
+            Algorithm algorithm = Algorithm.HMAC256(secret);
+            JWTVerifier verifier = JWT.require(algorithm)
+                    .withClaim("username", username)
+                    .build();
+            DecodedJWT jwt = verifier.verify(token);
+            return true;
+        } catch (Exception e) {
+            e.getMessage();
+            log.error(e.getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * 获得token中的信息无需secret解密也能获得
+     * @return token中包含的用户名
+     */
+    public static String getUsername(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim("username").asString();
+        } catch (JWTDecodeException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 生成签名,5min后过期
+     * @param username 用户名
+     * @param secret 用户的密码
+     * @return 加密的token
+     */
+    public static String sign(String username, String secret) {
+        try {
+            Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
+            Algorithm algorithm = Algorithm.HMAC256(secret);
+            // 附带username信息
+            return JWT.create()
+                    .withClaim("username", username)
+                    .withExpiresAt(date)
+                    .sign(algorithm);
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+    }
+}

+ 85 - 0
src/main/java/com/fd/shiro/MyRealm.java

@@ -0,0 +1,85 @@
+package com.fd.shiro;
+
+import com.fd.entity.User;
+import com.fd.repository.UserRepository;
+import com.fd.util.R;
+import lombok.extern.log4j.Log4j2;
+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.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+@Log4j2
+@Service
+public class MyRealm extends AuthorizingRealm {
+
+
+    @Autowired
+    private UserRepository userRepository;
+
+
+
+    /**
+     * 大坑!,必须重写此方法,不然Shiro会报错
+     */
+    @Override
+    public boolean supports(AuthenticationToken token) {
+        return token instanceof JWTToken;
+    }
+
+    /**
+     * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
+     *
+     * principals: 是token
+     */
+    @Override
+    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+        String username = JWTUtil.getUsername(principals.toString());
+        User user = userRepository.findByUsername(username);
+        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
+        simpleAuthorizationInfo.addRole(user.getRole());
+
+        // db 添加权限时,用“,”隔开
+        Set<String> permission = new HashSet<>(Arrays.asList(user.getPermission().split(",")));
+        simpleAuthorizationInfo.addStringPermissions(permission);
+
+        return simpleAuthorizationInfo;
+    }
+
+    /**
+     * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
+     */
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
+        String token = (String) auth.getCredentials();
+        log.warn("token: {}", token);
+        // 解密获得username,用于和数据库进行对比
+        String username = JWTUtil.getUsername(token);
+        if (username == null) {
+            throw new AuthenticationException("token invalid");
+        }
+
+        User user = userRepository.findByUsername(username);
+        if (user == null) {
+            throw new AuthenticationException("User didn't existed!");
+        }
+
+
+        if (! JWTUtil.verify(token, username, user.getPassword())) {
+//            throw new AuthenticationException("Username or password error");
+            throw new AuthenticationException("token invalid");
+        }
+
+        return new SimpleAuthenticationInfo(token, token, "my_realm");
+    }
+}

+ 148 - 0
src/main/java/com/fd/shiro/ShiroConfig.java

@@ -0,0 +1,148 @@
+package com.fd.shiro;
+
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import lombok.extern.log4j.Log4j2;
+import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
+import org.apache.shiro.mgt.DefaultSubjectDAO;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.http.MediaType;
+
+import javax.servlet.Filter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+@Log4j2
+@Configuration
+public class ShiroConfig {
+
+    @Bean("securityManager")
+    public DefaultWebSecurityManager getManager(MyRealm realm) {
+        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
+        // 使用自己的realm
+        manager.setRealm(realm);
+
+        /*
+         * 关闭shiro自带的session,详情见文档
+         * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
+         */
+        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
+        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
+        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
+        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
+        manager.setSubjectDAO(subjectDAO);
+
+        return manager;
+    }
+
+    @Bean("shiroFilter")
+    public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) {
+        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
+
+        // 添加自己的过滤器并且取名为jwt
+        Map<String, Filter> filterMap = new HashMap<>();
+        filterMap.put("jwt", new JWTFilter());
+
+
+
+        factoryBean.setFilters(filterMap);
+
+        factoryBean.setSecurityManager(securityManager);
+        factoryBean.setUnauthorizedUrl("/401");
+
+        /*
+         * 自定义url规则
+         * http://shiro.apache.org/web.html#urls-
+         */
+        Map<String, String> filterRuleMap = new HashMap<>();
+
+        filterRuleMap.put("/login", "anon");
+
+        // swagger 不拦截
+        filterRuleMap.put("/swagger-resources/**", "anon");
+        filterRuleMap.put("/webjars/**", "anon");
+        filterRuleMap.put("/v2/**", "anon");
+        filterRuleMap.put("/swagger-ui.html/**", "anon");
+
+
+        // 所有请求通过我们自己的JWT Filter
+        filterRuleMap.put("/**", "jwt");
+
+
+        // 访问401和404页面不通过我们的Filter
+        filterRuleMap.put("/401", "anon");
+        factoryBean.setFilterChainDefinitionMap(filterRuleMap);
+        return factoryBean;
+    }
+
+    /**
+     * 下面的代码是添加注解支持
+     */
+    @Bean
+    @DependsOn("lifecycleBeanPostProcessor")
+    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+        // 强制使用cglib,防止重复代理和可能引起代理出错的问题
+        // https://zhuanlan.zhihu.com/p/29161098
+        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
+        return defaultAdvisorAutoProxyCreator;
+    }
+
+    @Bean
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
+    }
+
+    @Bean
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
+        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
+        advisor.setSecurityManager(securityManager);
+        return advisor;
+    }
+
+
+    /**
+     * fastJson相关设置
+     * Dto包含json,需要配置不然会异常
+     * @return
+     */
+    @Bean
+    public HttpMessageConverters customConverters() {
+        log.warn("run customConverters");
+
+
+        FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();
+
+        // 创建FastJson信息转换对象
+        FastJsonConfig fastJsonConfig = new FastJsonConfig();
+
+
+        // 设置全程返回时间
+        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
+        // 设置返回值为null是时输出,不写的话,null 字段 不返回。也可以设置返回空串
+        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
+        fastJson.setFastJsonConfig(fastJsonConfig);
+
+        //3、中文乱码解决方案
+        List<MediaType> mediaTypeList = new ArrayList<>();
+        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
+        mediaTypeList.add(MediaType.valueOf("text/html;charset=UTF-8"));
+
+
+        //4、将转换规则应用于转换对象
+        fastJson.setSupportedMediaTypes(mediaTypeList);
+
+
+        return new HttpMessageConverters(fastJson);
+    }
+}

+ 2 - 0
src/main/resources/application-dev.properties

@@ -6,6 +6,8 @@ spring.datasource.password=root
 
 logging.file=log/cesium.log
 
+base.path=/root/gis/data
+
 input.file.path.model=/root/gis/cesium/input/model/
 output.file.path.model=/root/gis/cesium/output/model/
 

+ 1 - 1
src/main/resources/application.properties

@@ -15,4 +15,4 @@ spring.jpa.open-in-view=false
 spring.task.pool.corePoolSize=10
 spring.task.pool.maxPoolSize=100
 spring.task.pool.keepAliveSeconds=100
-spring.task.pool.queueCapacity=100
+spring.task.pool.queueCapacity=100