Spring Cloud gateway 自定义过滤器GatewayFilter

package com.rk.unified.gateway.filter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.MultiValueMap;

import com.rk.unified.common.component.JwtProperties;
import com.rk.unified.common.exception.AuthenticationException;
import com.rk.unified.common.utils.JwtUtils;
import com.rk.unified.common.vo.Cuser;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {
   
   @Autowired
   JwtProperties jwtProperties;
   
   @Autowired
   JwtUtils jwtUtils;
   
    AntPathMatcher antPathMatcher = new AntPathMatcher();

    public AuthorizeGatewayFilterFactory() {
        super(Config.class);
        log.info("Loaded AuthorizeGatewayFilterFactory [Authorize]");
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled", "auth", "permitAll");
    }

    @Override
    public GatewayFilter apply(AuthorizeGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {

            if (!config.isEnabled()) {
                return chain.filter(exchange);
            }
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();
            
            String requestPath = request.getPath().pathWithinApplication().value();
            
            log.info("{} {}", request.getMethodValue(), request.getURI());
            
            if(log.isDebugEnabled()) {
               log.debug("QueryParams: {}", request.getQueryParams());
               log.debug("Headers: {}", request.getHeaders());
            }

            //AntMatcher匹配
            if (config.getPermitAllList().stream().anyMatch(pattern -> antPathMatcher.match(pattern, requestPath))) {
               return chain.filter(exchange);
            }
            
            //========================================================
            //以上内容都不要修改,token、权限等各种校验的相关内容都写在下面
            //========================================================
            
            Cuser cuser = null;
            
            try {
               String token = getToken(request);
               cuser = jwtUtils.getCuser(token);
            }catch (AuthenticationException e) {
               return ServerHttpUtils.getErrorResponseMono(response, HttpStatus.UNAUTHORIZED, e);
         }
            
            if(config.isAuth()){
//             List<Long> roleIds = jwtTokenUtil.getRoleIdsFromToken(authToken);
//             String uri = request.getMethodValue().toUpperCase() + " " + request.getPath().pathWithinApplication().value();
//             //鉴权
//             boolean authorized = carSysService.isAuthorized(uri, JSON.toJSONString(roleIds));
//             if(!authorized){
//                return ServerHttpUtils.getErrorResponseMono(response, HttpStatus.FORBIDDEN, "没有足够的权限执行此操作");
//             }
            }
            
            return chain.filter(exchange);
        };
    }
    
    public String getToken(ServerHttpRequest request) {
      // 通过 header 获取
      String headerName = jwtProperties.getHeaderName();
      String headerPrefix = jwtProperties.getHeaderPrefix();
      boolean findHeader = false;
      HttpHeaders headers = request.getHeaders();
       if(headers.containsKey(headerName)) {
         findHeader = true;
         String header = headers.getFirst(headerName);
         if (StringUtils.startsWithIgnoreCase(header, headerPrefix)) {
            return header.substring(headerPrefix.length());
         } else {
            throw AuthenticationException.error();
         }
      }

       //cookie
      if (!findHeader) {
         String cookieName = jwtProperties.getCookieName();
         MultiValueMap<String, HttpCookie> cookies = request.getCookies();
         if(cookies != null && cookies.containsKey(cookieName)){
            return cookies.get(cookieName).get(0).getValue();
         }
      }

      throw AuthenticationException.none();
   }

    public static class Config {
        // 控制是否开启认证
        private boolean enabled;
        // 是否校验权限
        private boolean auth;

        private String permitAll;

        private List<String> permitAllList;

        public Config() {
        }

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }

        public boolean isAuth() {
            return auth;
        }

        public void setAuth(boolean auth) {
            this.auth = auth;
        }

        public String getPermitAll() {
            return permitAll;
        }

        public void setPermitAll(String permitAll) {
            this.permitAll = permitAll;
        }

        public List<String> getPermitAllList() {
            if (permitAllList == null) {
                if (StringUtils.isNotBlank(permitAll)) {
                    permitAllList = Arrays.asList(StringUtils.split(permitAll, " "));
                } else {
                    permitAllList = new ArrayList<>();
                }
            }
            return permitAllList;
        }

        public void setPermitAllList(List<String> permitAllList) {
            this.permitAllList = permitAllList;
        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值