Spring Security OAuth2.0(23):分布式系统授权-转发明文给微服务 📅 2026/7/17 4:59:51 转发明文给微服务通过zuul过滤器的方式实现目的是让下游微服务能够很方便的获取到当前的登录用户信息明文token)(1) 实现zuul前置过滤器完成当前登录用户信息提取并放入转发微服务的request 中添加AuthFilterimportcom.alibaba.fastjson.JSON;importcom.it2.security.distributed.util.EncryptUtil;importcom.netflix.zuul.ZuulFilter;importcom.netflix.zuul.context.RequestContext;importcom.netflix.zuul.exception.ZuulException;importorg.springframework.security.core.Authentication;importorg.springframework.security.core.GrantedAuthority;importorg.springframework.security.core.context.SecurityContextHolder;importorg.springframework.security.oauth2.provider.OAuth2Authentication;importorg.springframework.security.oauth2.provider.OAuth2Request;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;publicclassAuthFilterextendsZuulFilter{OverridepublicStringfilterType(){returnpre;// 前拦截}OverridepublicintfilterOrder(){return0;//最优先}OverridepublicbooleanshouldFilter(){returntrue;}OverridepublicObjectrun()throwsZuulException{RequestContextcurrentContextRequestContext.getCurrentContext();AuthenticationauthenticationSecurityContextHolder.getContext().getAuthentication();if(!(authenticationinstanceofOAuth2Authentication)){//无token访问网关内网资源的情况目前仅有uaa服务直接暴露returnnull;}OAuth2AuthenticationoAuth2Authentication(OAuth2Authentication)authentication;AuthenticationuserAuthenticationoAuth2Authentication.getUserAuthentication();//取出用户身份信息StringprincipaluserAuthentication.getName();//取出用户权限ListStringauthoritiesnewArrayList();//从userAuthentication取出权限放在authoritiesuserAuthentication.getAuthorities().stream().forEach(c-authorities.add(((GrantedAuthority)c).getAuthority()));OAuth2RequestoAuth2RequestoAuth2Authentication.getOAuth2Request();//请求参数MapString,StringrequestParametersoAuth2Request.getRequestParameters();//请求的参数列表MapString,ObjectjsonTokennewHashMap(requestParameters);//把身份信息和权限信息放在json中加入到http的headerif(userAuthentication!null){jsonToken.put(principal,principal);jsonToken.put(authorities,authorities);}//转发给微服务currentContext.addZuulRequestHeader(json-token,EncryptUtil.encodeUTF8StringBase64(JSON.toJSONString(jsonToken)));returnnull;}}工具类importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.io.UnsupportedEncodingException;importjava.net.URLDecoder;importjava.net.URLEncoder;importjava.util.Base64;publicclassEncryptUtil{privatestaticfinalLoggerloggerLoggerFactory.getLogger(EncryptUtil.class);publicstaticStringencodeBase64(byte[]bytes){StringencodedBase64.getEncoder().encodeToString(bytes);returnencoded;}publicstaticbyte[]decodeBase64(Stringstr){byte[]bytesnull;bytesBase64.getDecoder().decode(str);returnbytes;}publicstaticStringencodeUTF8StringBase64(Stringstr){Stringencodednull;try{encodedBase64.getEncoder().encodeToString(str.getBytes(utf-8));}catch(UnsupportedEncodingExceptione){logger.warn(不支持的编码格式,e);}returnencoded;}publicstaticStringdecodeUTF8StringBase64(Stringstr){Stringdecodednull;byte[]bytesBase64.getDecoder().decode(str);try{decodednewString(bytes,utf-8);}catch(UnsupportedEncodingExceptione){logger.warn(不支持的编码格式,e);}returndecoded;}publicstaticStringencodeURL(Stringurl){Stringencodednull;try{encodedURLEncoder.encode(url,utf-8);}catch(UnsupportedEncodingExceptione){logger.warn(URLEncode失败,e);}returnencoded;}publicstaticStringdecodeURL(Stringurl){Stringdecodednull;try{decodedURLDecoder.decode(url,utf-8);}catch(UnsupportedEncodingExceptione){logger.warn(URLDecode失败,e);}returndecoded;}}2配置filter configimportcom.it2.security.distributed.gateway.filter.AuthFilter;importorg.springframework.boot.web.servlet.FilterRegistrationBean;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.Ordered;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;importorg.springframework.web.filter.CorsFilter;ConfigurationpublicclassZuulConfig{BeanpublicAuthFilterpreFilter(){returnnewAuthFilter();}BeanpublicFilterRegistrationBeancorsFilter(){finalUrlBasedCorsConfigurationSourcesourcenewUrlBasedCorsConfigurationSource();finalCorsConfigurationconfignewCorsConfiguration();config.setAllowCredentials(true);config.addAllowedOrigin(*);config.addAllowedHeader(*);config.addAllowedMethod(*);config.setMaxAge(18000L);source.registerCorsConfiguration(/**,config);CorsFiltercorsFilternewCorsFilter(source);FilterRegistrationBeanbeannewFilterRegistrationBean(corsFilter);bean.setOrder(Ordered.HIGHEST_PRECEDENCE);returnbean;}}