zoukankan      html  css  js  c++  java
  • SpringCloud(10) ------>微服务下的Security

    一、搭建认证中心

    1、新建security-server认证中心

     父工程下 new modle-->maven项目-->项目名

    2、向pom文件添加依赖

      <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <!--jwt-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.0</version>
            </dependency>
    
            <!--eureka客户端client-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!--actuator-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <!--security-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <!--mysql依赖-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--mybatis plus依赖-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.1</version>
            </dependency>

    3、application.yml配置

    spring:
      profiles:
        active: default
    
    #####################客户端单节点配置###################
    ---
    spring:
      application:
        name: security-server
      profiles: default
      #mysql
      datasource: #数据源
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: root
        url: jdbc:mysql://localhost:3306/stmg?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    server:
      port: 8085 #运行端口号
    
    eureka:
      instance:
        lease-renewal-interval-in-seconds: 5
        #续约更新时间间隔
        lease-expiration-duration-in-seconds: 15
        #续约更新时间间隔
        hostname: localhost
        #指定主机地址
        instance-id: ${spring.cloud.client.ip-address}:${server.port}
      client:
        healthcheck:
          enabled: true
        register-with-eureka: true
        #注册到Eureka的注册中心
        fetch-registry: true
        #获取注册实例列表
        service-url:
          defaultZone:  http://localhost:8761/eureka
          #配置注册中心地址
        registry-fetch-interval-seconds: 10
        # 设置服务消费者从注册中心拉取服务列表的间隔
    
    #mybatis-plus
    mybatis-plus:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.donleo.security.model
      configuration:
        map-underscore-to-camel-case: true
    
    #log
    logging:
      level:
        com.donleo.security.mapper: debug
    
    jwt:
      #定义盐  密码
      secret: mySecret
      #过期时间(s)
      expiration: 1800
      #token 的类型 说明他以 bearer 开头
      tokenHead: bearer
      #token 对应的 key
      tokenHeader: Authorization
    #  {Authorization: "bearer sdfdsfsdfsdfdsfsdfadfdsf"}

    4、config配置

      1)security配置

    package com.donleo.security.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    /**
     * @author liangd
     * @since 2021-01-15 17:36
     */
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors().and()
                    .csrf().disable()
                    .sessionManagement()// 基于token,所以不需要 securityContext
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/css/**", "/js/**", "/fonts/**", "/user/login", "/user/register","/user/checkAuth").permitAll() //都可以访问
                    .antMatchers(HttpMethod.OPTIONS).permitAll()
                    .anyRequest().authenticated() // 任何请求都需要认证
                    .and()
                    .userDetailsService(userDetailsService)
            ;
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

      2)跨域拦截配置

    package com.donleo.security.config;
    
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    /**
     * @author liangd
     * @since 2021-01-15 17:38
     */
    @Configuration
    @Order(1)
    public class FilterConfig {
        /**
         * SpringBoot升级2.4.0 需要将addAllowedOrigin替换成.addAllowedOriginPattern
         */
        private CorsConfiguration buildConfig(){
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedHeader("*"); // 允许任何的head头部
            corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用
            corsConfiguration.addAllowedMethod("*"); // 允许任何的请求方法
            corsConfiguration.setAllowCredentials(true);
            return corsConfiguration;
        }
    
        /**
         * 添加CorsFilter拦截器,对任意的请求使用
         * @return CorsFilter
         */
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", buildConfig());
            return new CorsFilter(source);
        }
    }

    5、jwtTokenUtil工具类

    package com.donleo.security.utils;
    
    
    import com.donleo.security.model.User;
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.util.*;
    import java.util.stream.Collectors;
    
    /**
     * JwtToken生成的工具类
     * JWT token的格式:header.payload.signature
     * header的格式(算法、token的类型):
     * {"alg": "HS512","typ": "JWT"}
     * payload的格式(用户名、创建时间、生成时间):
     * {"sub":"wang","created":1489079981393,"exp":1489684781}
     * signature的生成算法:
     * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
     */
    @Component
    public class JwtTokenUtil {
        private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
        private static final String CLAIM_KEY_USERNAME = "sub";
        private static final String CLAIM_KEY_CREATED = "created";
        private static final String CLAIM_KEY_AUTHORITY = "auth";
    
        @Value("${jwt.secret}")
        private String secret;
        @Value("${jwt.expiration}")
        private Long expiration;
    
        /**
         * 根据负责生成JWT的token
         */
        private String generateToken(Map<String, Object> claims) {
            return Jwts.builder()
                    .setClaims(claims)
                    .setExpiration(generateExpirationDate())
                    .signWith(SignatureAlgorithm.HS512, secret)
                    .compact();
        }
    
        /**
         * 从token中获取JWT中的负载
         */
        private Claims getClaimsFromToken(String token) {
            Claims claims = null;
            try {
                claims = Jwts.parser()
                        .setSigningKey(secret)
                        .parseClaimsJws(token)
                        .getBody();
            } catch (Exception e) {
                LOGGER.info("JWT格式验证失败:{}", token);
            }
            return claims;
        }
    
        /**
         * 生成token的过期时间
         */
        private Date generateExpirationDate() {
            return new Date(System.currentTimeMillis() + expiration * 1000);
        }
    
        /**
         * 从token中获取登录用户名(用户编号)
         */
        public String getUserCodeFromToken(String token) {
            String userCode;
            try {
                Claims claims = getClaimsFromToken(token);
                userCode = claims.getSubject();
            } catch (Exception e) {
                userCode = null;
            }
            return userCode;
        }
    
        /**
         * 验证token是否还有效
         *
         * @param token       客户端传入的token
         * @param userDetails 从数据库中查询出来的用户信息
         */
        public boolean validateToken(String token, UserDetails userDetails) {
            String userCode = getUserCodeFromToken(token);
            return userCode.equals(userDetails.getUsername()) && !isTokenExpired(token);
        }
    
        /**
         * 判断token是否已经失效
         */
        private boolean isTokenExpired(String token) {
            Date expiredDate = getExpiredDateFromToken(token);
            return expiredDate.before(new Date());
        }
    
        /**
         * 从token中获取过期时间
         */
        private Date getExpiredDateFromToken(String token) {
            Claims claims = getClaimsFromToken(token);
            return claims.getExpiration();
        }
    
        /**
         * 根据用户信息生成token(用户编号、时间以及权限)
         *
         * 如果采用远程调用来判断用户是否有权限,这里不需要将权限放进token中
         */
        public String generateToken(User user) {
            Map<String, Object> claims = new HashMap<>();
            Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
            Set<Object> collect = authorities.stream().filter(p -> StringUtils.hasText(p.getAuthority()))
                    .map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
            claims.put(CLAIM_KEY_USERNAME, user.getCode());
            claims.put(CLAIM_KEY_CREATED, new Date());
            claims.put(CLAIM_KEY_AUTHORITY, collect);
            return generateToken(claims);
        }
    
        /**
         * 判断token是否可以被刷新
         */
        public boolean canRefresh(String token) {
            return !isTokenExpired(token);
        }
    
        /**
         * 刷新token
         */
        public String refreshToken(String token) {
            Claims claims = getClaimsFromToken(token);
            claims.put(CLAIM_KEY_CREATED, new Date());
            return generateToken(claims);
        }
    }

    6、model层

     1)User实体类实现UserDetails接口
    package com.donleo.security.model;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.Collection;
    import java.util.Date;
    import java.util.Set;
    
    /**
     * <p>
     * 用户表
     * </p>
     *
     * @author liangd
     * @since 2020-12-21
     */
    @Data
    @EqualsAndHashCode(callSuper = false)
    public class User implements UserDetails {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * id
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 用户编号
         */
        private String code;
    
        /**
         * 用户名
         */
        private String username;
    
        /**
         * 密码
         */
        private String password;
    
        /**
         * 权限集合
         */
        @JsonIgnoreProperties(ignoreUnknown = true)
        private Set<? extends GrantedAuthority> authorities;
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return this.authorities;
        }
    
        @Override
        public String getPassword() {
            return this.password;
        }
    
        @Override
        public String getUsername() {
            return this.username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        public void setAccountNonExpired(boolean accountNonExpired) {
    
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        public void setAccountNonLocked(boolean accountNonLocked) {
    
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        public void setCredentialsNonExpired(boolean credentialsNonExpired) {
    
        }
    
        @Override
        public boolean isEnabled() {
            if (this.dataEnable == null) {
                return false;
            }
            return "yes".equals(this.dataEnable);
        }
    
        public void setEnabled(boolean enabled) {
    
        }
    }
     2)Permission实体类实现GrantedAuthority接口
    package com.donleo.security.model;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.fasterxml.jackson.annotation.JsonFormat;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.NoArgsConstructor;
    import org.springframework.security.core.GrantedAuthority;
    
    import java.util.Date;
    
    /**
     * <p>
     * 权限表
     * </p>
     *
     * @author liangd
     * @since 2020-12-21
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    public class Permission implements GrantedAuthority {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * id
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 权限编号
         */
        private String code;
    
        /**
         * 父id  0根节点
         */
        private Integer pid;
    
        /**
         * 权限名
         */
        private String name;
    
        /**
         * 权限值
         */
        private String value;
    
        /**
         * 类型 1菜单 2方法
         */
        private Integer type;
    
        /**
         * 方法路径
         */
        private String uri;
    
        /**
         * 创建时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date createTime;
    
        /**
         * 是否可用
         */
        private String dataEnable;
    
        @Override
        public String getAuthority() {
            return this.uri;
        }
    }

    7、service层,自定义UserDetailsService

    package com.donleo.security.service.impl;
    
    import com.donleo.security.model.Permission;
    import com.donleo.security.model.User;
    import com.donleo.security.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    
    import java.util.HashSet;
    import java.util.List;
    
    /**
     * @author liangd
     * date 2020-12-08 19:10
     * code 自定义UserDetailsService
     */
    @Service("userDetailsService")
    public class UserDetailsServiceImpl implements UserDetailsService {
    
        @Autowired
        UserService userService;
    
        /**
         * 从数据库读取用户名认证
         * @param code 用户编号
         * @return UserDetails
         */
        @Override
        public UserDetails loadUserByUsername(String code) throws UsernameNotFoundException {
            User user= userService.getUserByCode(code);
            List<Permission> permissionList= userService.getPermissionsByUserCode(user.getCode());
            //获取用户拥有的权限
            HashSet<Permission> permissions = new HashSet<>(permissionList);
            user.setAuthorities(permissions);
            return user;
        }
    }

    8、启动类

    /**
     * @author liangd
     * @since 2021-01-15 17:18
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    @MapperScan("com.donleo.security.mapper")
    public class SecurityApp {
        public static void main(String[] args){
            SpringApplication.run(SecurityApp.class,args);
        }
    }

    二、zuul网关配置

    (一)在网关拦截器处,从token中获取权限进行鉴权

    1、向pom文件添加依赖

          <!--jwt-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.0</version>
            </dependency>

    2、application.yml添加配置

    jwt:
      #定义盐  密码
      secret: mySecret
      #过期时间(s)
      expiration: 1800
      #token 的类型 说明他以 bearer 开头
      tokenHead: bearer
      #token 对应的 key
      tokenHeader: Authorization

    3、jwtTokenUtil工具类

      在jwt的工具类添加获取权限路径的方法

     /**
         * 从token中获取权限uri
         */
        public Set<String> getAuthsFromToken(String token) throws  Exception{
            Claims claims = getClaimsFromToken(token);
            return getAuthsFromClaims(claims);
        }
    
        private Set<String> getAuthsFromClaims(Claims claims) {
            Object o = claims.get(CLAIM_KEY_AUTHORITY);
            HashSet hashSet =new HashSet((ArrayList)o);
            return hashSet;
        }

    4、自定义网关Filter拦截器

    package com.donleo.zuul.filter;
    
    import com.alibaba.fastjson.JSONObject;
    import com.donleo.zuul.common.CommonResult;
    import com.donleo.zuul.service.UserService;
    import com.donleo.zuul.utils.JwtTokenUtil;
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import io.jsonwebtoken.ExpiredJwtException;
    import org.apache.commons.lang.StringUtils;
    import org.apache.http.HttpStatus;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.CountDownLatch;
    
    /**
     * 自定义网关过滤器
     *
     * @author liangd
     * @since 2021-01-12 18:52
     */
    @Component
    public class LogFilter extends ZuulFilter {
        /**
         * 分割成数组
         */
        @Value("#{'${pathList}'.split(',')}")
        private List<String> pathList;
    
        @Autowired
        private JwtTokenUtil jwtTokenUtil;
    
        @Autowired
        private UserService userService;
    
        /**
         * 过滤器的类型。可选值有:
         * pre - 前置过滤
         * route - 路由后过滤
         * error - 异常过滤
         * post - 远程服务调用后过滤
         */
        @Override
        public String filterType() {
            return "pre";
        }
    
        /**
         * 同种类的过滤器的执行顺序。
         * 按照返回值的自然升序执行。
         * 值越小,级别越高
         */
        @Override
        public int filterOrder() {
            return 0;
        }
    
        /**
         * 哪些请求会被过滤
         */
        @Override
        public boolean shouldFilter() {
       /*     RequestContext currentContext = RequestContext.getCurrentContext();
            HttpServletRequest request = currentContext.getRequest();
            String requestURI = request.getRequestURI();
            //只有/api/w 开头的会被过滤
            return requestURI.startsWith("/api/w");*/
            //true 默认所有请求都会过滤
            return true;
        }
    
        @Override
        public Object run() {
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletResponse response = requestContext.getResponse();
            response.setContentType("text/html;charset=UTF-8");
            HttpServletRequest request = requestContext.getRequest();
            String uri = request.getRequestURI();
            //哪些路径可以直接放行
            boolean a = pathList.stream().anyMatch(path -> StringUtils.contains(uri, path));
            //第一种方式,从token读取权限
            //第二种方式,远程调用security服务,将判断逻辑在security服务中判断是否有访问该路径的权限
            if (a) {
                return null;
            }
            String authorization = request.getHeader("Authorization");
            if (authorization == null) {
                requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.unauthorized("未登录")));
                requestContext.setSendZuulResponse(false);
                return null;
            }
            String token = StringUtils.substring(authorization, "bearer".length()).trim();
            /************************第一种方式,从token读取权限*******************************/
           Set<String> auths = null;
            try {
                auths = jwtTokenUtil.getAuthsFromToken(token);
            } catch (Exception e) {
                // 处理token过期
                if (e instanceof ExpiredJwtException) {
                    requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.unauthorized("token已过期")));
                    requestContext.setSendZuulResponse(false);
                    return null;
                }
                e.printStackTrace();
            }
            //验证权限
            assert auths != null;
            boolean b = auths.stream().anyMatch(auth -> StringUtils.equals(auth, uri));
            if (!b) {
                requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.forbidden("没有访问权限")));
                requestContext.setSendZuulResponse(false);
                return null;
            }
            return null;
         
    }

    (二)用OpenFeign远程调用接口,在认证中心进行鉴权

      当一个用户的权限过多,可以考虑通过远程调用接口的方式进行鉴权,这里采用OpenFeign调用接口的方式。

    1、向pom文件新增依赖

          <!--声明式服务调用openfeign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>

    2、service层

    package com.donleo.zuul.service;
    
    import com.donleo.zuul.common.CommonResult;
    import com.donleo.zuul.config.FeignClientConfig;
    import com.donleo.zuul.service.impl.UserServiceFallbackFactory;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    /**
     * @author liangd
     * @since 2021-01-16 11:16
     */
    @FeignClient(value = "security-server",fallbackFactory = UserServiceFallbackFactory.class,configuration = FeignClientConfig.class)
    public interface UserService {
    
        @PostMapping("/user/checkAuth")
        CommonResult checkAuth(@RequestParam("userCode") String userCode, @RequestParam("uri") String uri);
    }

    3、fallbackFactory服务降级处理

    package com.donleo.zuul.service.impl;
    
    import com.donleo.zuul.common.CommonResult;
    import com.donleo.zuul.service.UserService;
    import feign.hystrix.FallbackFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @author liangd
     * @since 2021-01-16 11:24
     */
    @Component
    public class UserServiceFallbackFactory implements FallbackFactory<UserService> {
        @Override
        public UserService create(Throwable throwable) {
            return (userCode, uri) -> CommonResult.failed("连接异常");
        }
    }

    4、自定义网关Filter拦截器

     @Override
        public Object run() {
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletResponse response = requestContext.getResponse();
            response.setContentType("text/html;charset=UTF-8");
            HttpServletRequest request = requestContext.getRequest();
            String uri = request.getRequestURI();
            //哪些路径可以直接放行
            boolean a = pathList.stream().anyMatch(path -> StringUtils.contains(uri, path));
            //第一种方式,从token读取权限
            //第二种方式,远程调用security服务,将判断逻辑在security服务中判断是否有访问该路径的权限
            if (a) {
                return null;
            }
            String authorization = request.getHeader("Authorization");
            if (authorization == null) {
                requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.unauthorized("未登录")));
                requestContext.setSendZuulResponse(false);
                return null;
            }
            String token = StringUtils.substring(authorization, "bearer".length()).trim();
      
            /************************第二种方式,远程调用security服务**************************/
            try {
                jwtTokenUtil.isTokenExpired(token);
            } catch (Exception e) {
                if (e instanceof ExpiredJwtException) {
                    requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.unauthorized("token已过期")));
                    requestContext.setSendZuulResponse(false);
                    return null;
                }
                e.printStackTrace();
            }
            String userCode = jwtTokenUtil.getUserCodeFromToken(token);
            CommonResult commonResult = userService.checkAuth(userCode, uri);
            long code = commonResult.getCode();
            if (code == 200) {
                return null;
            } else if (code == 500) {
                requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.forbidden("没有访问权限")));
                requestContext.setSendZuulResponse(false);
                return null;
            } else {
                requestContext.setResponseBody(JSONObject.toJSONString(CommonResult.failed("未知错误")));
                requestContext.setSendZuulResponse(false);
                return null;
            }
        }

     5、启动类上添加注解@EnableFeignClients

    作者:donleo123
    本文如对您有帮助,还请多推荐下此文,如有错误欢迎指正,相互学习,共同进步。
  • 相关阅读:
    Java数据类型转换
    Java数据类型
    Revisiting Network Support for RDMA
    FBOSS: Building Switch Software at Scale
    Edge-assisted Traffic Engineering and applications in the IoT
    Edge Intelligence: On-Demand Deep Learning Model Co-Inference with Device-Edge Synergy
    ARVE: Augmented Reality Applications in Vehicle to Edge Networks
    Deployment Characteristics of "The Edge" in Mobile Edge Computing
    CABaRet: Leveraging Recommendation Systems for Mobile Edge Caching
    Anveshak: Placing Edge Servers In The Wild
  • 原文地址:https://www.cnblogs.com/donleo123/p/14286382.html
Copyright © 2011-2022 走看看