mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	fix: 积木报表 API 数据集解析时 token 未正确解析的问题
This commit is contained in:
		| @@ -1,11 +1,8 @@ | |||||||
| package cn.iocoder.yudao.module.visualization.framework.jmreport.config; | package cn.iocoder.yudao.module.visualization.framework.jmreport.config; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; |  | ||||||
| import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; | import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; | ||||||
| import cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl; | import cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl; | ||||||
| import cn.iocoder.yudao.module.visualization.framework.jmreport.core.web.JmReportTokenFilter; |  | ||||||
| import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; | import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; | ||||||
| import org.springframework.boot.web.servlet.FilterRegistrationBean; |  | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.ComponentScan; | import org.springframework.context.annotation.ComponentScan; | ||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| @@ -25,12 +22,4 @@ public class JmReportConfiguration { | |||||||
|         return new JmReportTokenServiceImpl(oAuth2TokenApi); |         return new JmReportTokenServiceImpl(oAuth2TokenApi); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Bean |  | ||||||
|     @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") |  | ||||||
|     public FilterRegistrationBean<JmReportTokenFilter> registerMyAnotherFilter(OAuth2TokenApi oAuth2TokenApi){ |  | ||||||
|         FilterRegistrationBean<JmReportTokenFilter> bean = new FilterRegistrationBean<>(); |  | ||||||
|         bean.setOrder(WebFilterOrderEnum.JM_TOKEN_FILTER); |  | ||||||
|         bean.setFilter(new JmReportTokenFilter(oAuth2TokenApi)); |  | ||||||
|         return bean; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.visualization.framework.jmreport.core.service; | |||||||
|  |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.common.exception.ServiceException; | import cn.iocoder.yudao.framework.common.exception.ServiceException; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | ||||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; | import cn.iocoder.yudao.framework.security.core.LoginUser; | ||||||
| import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | ||||||
| import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||||||
| @@ -10,6 +11,9 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; | |||||||
| import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; | import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
| import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; | import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; | ||||||
|  | import org.springframework.http.HttpHeaders; | ||||||
|  |  | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * {@link JmReportTokenServiceI} 实现类,提供积木报表的 Token 校验、用户信息的查询等功能 |  * {@link JmReportTokenServiceI} 实现类,提供积木报表的 Token 校验、用户信息的查询等功能 | ||||||
| @@ -18,9 +22,33 @@ import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; | |||||||
|  */ |  */ | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| public class JmReportTokenServiceImpl implements JmReportTokenServiceI { | public class JmReportTokenServiceImpl implements JmReportTokenServiceI { | ||||||
|  |     private static final String JM_TOKEN_HEADER = "X-Access-Token"; | ||||||
|  |     /** | ||||||
|  |      * 系统内置请求头 | ||||||
|  |      */ | ||||||
|  |     private static final String TOKEN_HEADER = "Authorization"; | ||||||
|  |     /** | ||||||
|  |      * auth 相关格式 | ||||||
|  |      */ | ||||||
|  |     private static final String AUTHORIZATION_FORMAT = "Bearer %s"; | ||||||
|  |  | ||||||
|     private final OAuth2TokenApi oauth2TokenApi; |     private final OAuth2TokenApi oauth2TokenApi; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 修改请求的 head | ||||||
|  |      * | ||||||
|  |      * @return 新 head | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public HttpHeaders customApiHeader() { | ||||||
|  |         HttpHeaders header = new HttpHeaders(); | ||||||
|  |         HttpServletRequest request = ServletUtils.getRequest(); | ||||||
|  |         String token = request.getHeader(JM_TOKEN_HEADER); | ||||||
|  |  | ||||||
|  |         header.add(TOKEN_HEADER, String.format(AUTHORIZATION_FORMAT, token)); | ||||||
|  |         return header; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 校验 Token 是否有效,即验证通过 |      * 校验 Token 是否有效,即验证通过 | ||||||
|      * |      * | ||||||
| @@ -62,7 +90,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI { | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 获得用户编号 |      * 获得用户编号 | ||||||
|      * |      * <p> | ||||||
|      * 虽然方法名获得的是 username,实际对应到项目中是用户编号 |      * 虽然方法名获得的是 username,实际对应到项目中是用户编号 | ||||||
|      * |      * | ||||||
|      * @param token JmReport 前端传递的 token |      * @param token JmReport 前端传递的 token | ||||||
|   | |||||||
| @@ -1,132 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.visualization.framework.jmreport.core.web; |  | ||||||
|  |  | ||||||
| import cn.hutool.core.util.StrUtil; |  | ||||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; |  | ||||||
| import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |  | ||||||
| import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; |  | ||||||
| import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
|  |  | ||||||
| import javax.servlet.Filter; |  | ||||||
| import javax.servlet.FilterChain; |  | ||||||
| import javax.servlet.ServletException; |  | ||||||
| import javax.servlet.ServletRequest; |  | ||||||
| import javax.servlet.ServletResponse; |  | ||||||
| import javax.servlet.http.HttpServletRequest; |  | ||||||
| import javax.servlet.http.HttpServletRequestWrapper; |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.Enumeration; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
| import java.util.Optional; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 积木报表 token 处理,将积木报表请求头中的 token 转换成 spring security 的 auth head |  | ||||||
|  */ |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class JmReportTokenFilter implements Filter { |  | ||||||
|     /** |  | ||||||
|      * 积木 token 请求头 |  | ||||||
|      */ |  | ||||||
|     private static final String JM_TOKEN_HEADER = "X-Access-Token"; |  | ||||||
|     /** |  | ||||||
|      * 系统内置请求头 |  | ||||||
|      */ |  | ||||||
|     private static final String TOKEN_HEADER = "Authorization"; |  | ||||||
|     /** |  | ||||||
|      * auth 相关格式 |  | ||||||
|      */ |  | ||||||
|     private static final String AUTHORIZATION_FORMAT = "Bearer %s"; |  | ||||||
|  |  | ||||||
|     private final OAuth2TokenApi oauth2TokenApi; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |  | ||||||
|         // 积木请求头 |  | ||||||
|         HttpServletRequest req = (HttpServletRequest) servletRequest; |  | ||||||
|         String token = req.getHeader(JM_TOKEN_HEADER); |  | ||||||
|         if (StrUtil.isNotEmpty(token)) { |  | ||||||
|             // 1. 增加请求头 |  | ||||||
|             HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req); |  | ||||||
|             requestWrapper.addHeader(TOKEN_HEADER, String.format(AUTHORIZATION_FORMAT, token)); |  | ||||||
|  |  | ||||||
|             OAuth2AccessTokenCheckRespDTO resp = oauth2TokenApi.checkAccessToken(token); |  | ||||||
|             Optional<LoginUser> optUser = Optional.ofNullable(resp) |  | ||||||
|                     .map( |  | ||||||
|                             t -> new LoginUser().setId(t.getUserId()) |  | ||||||
|                                     .setUserType(t.getUserType()) |  | ||||||
|                                     .setTenantId(t.getTenantId()) |  | ||||||
|                                     .setScopes(t.getScopes()) |  | ||||||
|                     ); |  | ||||||
|             if (optUser.isPresent()) { |  | ||||||
|                 // 2. 设置登录用户类型 |  | ||||||
|                 WebFrameworkUtils.setLoginUserType(servletRequest, optUser.get().getUserType()); |  | ||||||
|                 filterChain.doFilter(requestWrapper, servletResponse); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         filterChain.doFilter(servletRequest, servletResponse); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * request 包装类,用于修改 head |  | ||||||
|      * |  | ||||||
|      * <a href="https://stackoverflow.com/questions/2811769/adding-an-http-header-to-the-request-in-a-servlet-filter">add request head</a> |  | ||||||
|      */ |  | ||||||
|     public class HeaderMapRequestWrapper extends HttpServletRequestWrapper { |  | ||||||
|         /** |  | ||||||
|          * construct a wrapper for this request |  | ||||||
|          * |  | ||||||
|          * @param request |  | ||||||
|          */ |  | ||||||
|         public HeaderMapRequestWrapper(HttpServletRequest request) { |  | ||||||
|             super(request); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         private Map<String, String> headerMap = new HashMap<String, String>(); |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * add a header with given name and value |  | ||||||
|          * |  | ||||||
|          * @param name |  | ||||||
|          * @param value |  | ||||||
|          */ |  | ||||||
|         public void addHeader(String name, String value) { |  | ||||||
|             headerMap.put(name, value); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public String getHeader(String name) { |  | ||||||
|             String headerValue = super.getHeader(name); |  | ||||||
|             if (headerMap.containsKey(name)) { |  | ||||||
|                 headerValue = headerMap.get(name); |  | ||||||
|             } |  | ||||||
|             return headerValue; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * get the Header names |  | ||||||
|          */ |  | ||||||
|         @Override |  | ||||||
|         public Enumeration<String> getHeaderNames() { |  | ||||||
|             List<String> names = Collections.list(super.getHeaderNames()); |  | ||||||
|             for (String name : headerMap.keySet()) { |  | ||||||
|                 names.add(name); |  | ||||||
|             } |  | ||||||
|             return Collections.enumeration(names); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public Enumeration<String> getHeaders(String name) { |  | ||||||
|             List<String> values = Collections.list(super.getHeaders(name)); |  | ||||||
|             if (headerMap.containsKey(name)) { |  | ||||||
|                 values.add(headerMap.get(name)); |  | ||||||
|             } |  | ||||||
|             return Collections.enumeration(values); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 gaibu
					gaibu