赞
踩
上一篇博客开头说到了gateway服务之前调用有些特殊,那是因为webflux和spring-webmvc;
gateway不兼容spring-webmvc所以项目创建的时候也就剔除了,剔除之后无法使用HttpServletRequest,所以之前搭建的不能简单的替换zuul,改动太大。只能将zuul从安全认证这个模块中移除,然后独立成一个模块供gateway认证时调用。
改造之前的springsecurity,移除zuul相关依赖,在UserController中新增一个接口
- /**
- * 认证
- * @param token
- * @return
- */
- @RequestMapping(value = "/verificationToken",method = {RequestMethod.POST,RequestMethod.GET})
- @ResponseBody
- public ResultVO<Boolean> verificationToken(@RequestParam("token") String token){
-
- AuthUser authUser = JwtUtil.parseToken(token);
-
- authUser.getUsername();
-
- return Backtrack.success(true);
-
- }
此方法供gateway调用,Backtrack为一个统一返回和接收校验的类,用于抛请求异常。
- package com.cloudalibaba.securitypermission.common.methods;
-
- import com.cloudalibaba.securitypermission.common.vo.ResultVO;
-
- /**
- * 返回和接收校验
- * @author wqy
- * @version 1.0
- * @date 2020/6/9 15:52
- */
- public class Backtrack{
-
- /**
- * 成功的执行
- * @param t 数据体
- * @param msg 备注
- * @param <T> 泛型
- * @return
- */
- public static <T> ResultVO<T> success(T t, String msg){
-
- ResultVO<T> resultVO = new ResultVO<>();
-
- resultVO.setCode(10);
- resultVO.setData(t);
- resultVO.setMsg(msg);
-
- return resultVO;
-
- }
-
- /**
- * 成功的执行
- * @param t 数据体
- * @param <T> 泛型
- * @return
- */
- public static <T> ResultVO<T> success(T t){
-
- ResultVO<T> resultVO = new ResultVO<>();
-
- resultVO.setCode(10);
- resultVO.setData(t);
-
- return resultVO;
-
- }
-
- /**
- * 成功的执行
- * @param msg 备注
- * @param <T> 泛型
- * @return
- */
- public static <T> ResultVO<T> success(String msg){
-
- ResultVO<T> resultVO = new ResultVO<>();
-
- resultVO.setCode(10);
- resultVO.setMsg(msg);
-
- return resultVO;
-
- }
-
- /**
- * 失败的执行
- * @param t 数据体
- * @param msg 备注
- * @param <T> 泛型
- * @return
- */
- public static <T> ResultVO<T> errot(T t,String msg){
-
- ResultVO<T> resultVO = new ResultVO<>();
- resultVO.setCode(11);
- resultVO.setData(t);
- resultVO.setMsg(msg);
- return resultVO;
-
- }
-
- /**
- * 失败的执行
- * @param msg 备注
- * @param <T> 泛型
- * @return
- */
- public static <T> ResultVO<T> errot(String msg){
-
- ResultVO<T> resultVO = new ResultVO<>();
- resultVO.setCode(11);
- resultVO.setMsg(msg);
- return resultVO;
-
- }
-
- /**
- * 校验ResultVO结果
- * 如果code==10则成功其余则失败
- * @param resultVO
- * @return
- */
- public static <T> T checkData(ResultVO<T> resultVO){
-
- //判断返回结果是否是SuperEntity的子类
- //11为异常,失败
- if(resultVO.getCode()==11){
- throw new RuntimeException(resultVO.getMsg());
- }
- if(resultVO.getCode()==10){
- return resultVO.getData();
- }
- throw new RuntimeException("调用失败");
-
- }
-
- /**
- * 校验ResultVO结果
- * 如果code==10则成功其余则失败
- * @param resultVO
- * @return
- */
- public static String checkMsg(ResultVO<String> resultVO){
-
- //判断返回结果是否是SuperEntity的子类
- //11为异常,失败
- if(resultVO.getCode()==11){
- throw new RuntimeException(resultVO.getMsg());
- }
- if(resultVO.getCode()==10){
- return resultVO.getMsg();
- }
- throw new RuntimeException("调用失败");
-
- }
-
- }
然后修改AccessDeniedHandler和TokenExceptionHandler,这两个类是无权限和token异常
修改response.setContentType为response.setContentType("application/json; charset=utf-8");
这样安全框架这块就算修改完了。
修改gateway,创建上文中的filter文件夹。
并创建一个filter类
- package com.cloudalibaba.gateway.filter;
-
- import com.cloudalibaba.gateway.common.methods.Backtrack;
- import com.cloudalibaba.gateway.common.vo.ResultVO;
- import com.cloudalibaba.gateway.feign.SecuritypePermissionFeign;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cloud.gateway.filter.GatewayFilterChain;
- import org.springframework.cloud.gateway.filter.GlobalFilter;
- import org.springframework.core.Ordered;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.server.reactive.ServerHttpRequest;
- import org.springframework.stereotype.Component;
- import org.springframework.web.server.ServerWebExchange;
- import reactor.core.publisher.Mono;
-
- import java.util.Date;
- import java.util.List;
-
- /**
- * @author wqy
- * @version 1.0
- * @date 2020/8/1 15:23
- */
- @Component
- @Slf4j
- public class MyLogGateWayFilter implements GlobalFilter, Ordered {
-
- @Autowired
- private SecuritypePermissionFeign securitypePermissionFeign;
-
- @Override
- public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
-
- log.info("********come in MyLogGatewayFilter:" + new Date());
- ServerHttpRequest request = exchange.getRequest();
- System.out.println(request.getPath());
- System.out.println(request.getQueryParams());
- System.out.println(request.getHeaders().get("token"));
- HttpHeaders headers = request.getHeaders();
- List<String> strs = headers.get("token");
- //获取token并验证
- String token = strs.get(0);
- System.out.println(token);
- Boolean check = Backtrack.checkData(securitypePermissionFeign.verificationToken(token));
- System.out.println(check);
- return chain.filter(exchange);
- }
-
- @Override
- public int getOrder() {
- return 0;
- }
- }
创建feign,指向securitypermission
- package com.cloudalibaba.gateway.feign;
-
- import com.cloudalibaba.gateway.common.vo.ResultVO;
- import com.cloudalibaba.gateway.config.CustomizedConfiguration;
- import org.springframework.cloud.openfeign.FeignClient;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RequestParam;
-
- /**
- * @author wqy
- * @version 1.0
- * @date 2020/8/1 16:04
- */
- @FeignClient(value = "securitypermission")
- public interface SecuritypePermissionFeign {
-
- /**
- * 验证token
- * @param token
- * @return
- */
- @RequestMapping(value = "/verificationToken",method = {RequestMethod.POST})
- ResultVO<Boolean> verificationToken(@RequestParam("token") String token);
-
- }
这样按正常来说是可以进行调用了,但是!!!,这个是gateway,这样会报错(HttpMessageConverters),请求没问题,但是接受返回值的时候问题就来了,gateway没有对应的解析器去解析response(也可能是默认用错了解析器)。所以要进行一个转换。
- package com.cloudalibaba.gateway.config;
-
- import org.springframework.beans.factory.ObjectProvider;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
- import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.http.converter.HttpMessageConverter;
- import reactor.core.publisher.Mono;
-
- import java.util.Objects;
- import java.util.stream.Collectors;
-
- /**
- * 转换器
- * gateway通过feign调用的时候,gateway中没有相应的解析器(返回),所以会出现异常(HttpMessageConverters)
- * 然后将请求转成HttpMessageConverters即可
- * @author wqy
- */
- @Configuration
- public class GatewayConfig {
-
- @Bean
- KeyResolver userKeyResolver() {
- return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress());
- }
-
- @Bean
- @ConditionalOnMissingBean
- public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
- return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
- }
- }
这样就可以正常的访问了。
最后奉上代码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。