From a7d2d03fe177a58c22e960e9c87b32f7b05be74f Mon Sep 17 00:00:00 2001 From: CeDo <cedoo@qq.com> Date: 星期六, 01 五月 2021 22:57:48 +0800 Subject: [PATCH] add:添加小程序实名认证接口过滤(部分) --- springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java | 3 springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml | 39 +++ springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java | 369 +++++++++++++++++++----------------- springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java | 10 + springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java | 1 springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java | 21 +- springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java | 133 +++++++++++++ springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java | 17 + 8 files changed, 403 insertions(+), 190 deletions(-) diff --git a/springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java b/springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java index 3d71c1e..7fc7c6d 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java +++ b/springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java @@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject; import com.panzhihua.applets.weixin.CheckService; import com.panzhihua.applets.model.dtos.ComPbMemberCertificationDTO; +import com.panzhihua.common.constants.SecurityConstants; +import com.panzhihua.common.constants.UserConstants; import com.panzhihua.common.model.dtos.user.SysUserEditTipsDTO; import com.panzhihua.common.model.dtos.user.SysUserFeedbackDTO; import com.panzhihua.common.model.vos.community.*; @@ -21,6 +23,7 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.util.ObjectUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -51,6 +54,8 @@ private PartyBuildingService partyBuildingService; @Resource private CheckService checkService; + @Resource + private StringRedisTemplate stringRedisTemplate; @ApiOperation(value = "当前登录用户信息", response = LoginUserInfoVO.class) @GetMapping("info") @@ -118,6 +123,11 @@ if (R.isOk(r1)) { log.info("新增实名认证未通过通知成功【{}】", JSONObject.toJSONString(sysUserNoticeVO)); } + //清空缓存 + String userRoleKey = UserConstants.LOGIN_USER_INFO + this.getLoginUserInfo().getUserId(); + String userAppletRoleKey = SecurityConstants.ROLE_APPLETS_USER + this.getLoginUserInfo().getUserId(); + stringRedisTemplate.delete(userRoleKey); + stringRedisTemplate.delete(userAppletRoleKey); } else { //未通过发通知 /** diff --git a/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java b/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java index f4b32db..813603e 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java +++ b/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java @@ -16,5 +16,6 @@ public static final String APPLETS_ACCESS_MEDIA_ID ="APPLETS_ACCESS_MEDIA_ID";//小程序获取的access_token public static final String APPLETS_ACCESS_MEDIA_ID_TIME ="APPLETS_ACCESS_MEDIA_ID_TIME";//小程序获取的access_token - + public static final String ROLE_APPLETS_REAL_NAMED="applets:realnamed";//小程序用户实名角色 + public static final String ROLE_APPLETS_USER="applets:realnamed:user:";//小程序用户角色 } diff --git a/springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java b/springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java index 1c300d7..7ab3706 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java +++ b/springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java @@ -253,6 +253,7 @@ loginUserInfoVO.setIsmemberrole(1); } } + loginUserInfoVO.setIsRealNamed(sysUserDO.getIdCard()!=null); return R.ok(loginUserInfoVO); } diff --git a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java new file mode 100644 index 0000000..3f87049 --- /dev/null +++ b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java @@ -0,0 +1,17 @@ +package com.panzhihua.zuul.config; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@ConfigurationProperties(prefix = "applet.realname") +@Data +public class RealNamedConfig { + + private List<String> verify; + +} diff --git a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java index 8d74a7e..71bc6f9 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java +++ b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java @@ -1,5 +1,6 @@ package com.panzhihua.zuul.config; +import com.panzhihua.zuul.filters.AppletAuthenticationFilter; import com.panzhihua.zuul.filters.JWTAuthenticationTokenFilter; import com.panzhihua.zuul.filters.SercuritFilter; import com.panzhihua.zuul.handles.UserAuthAccessDeniedHandler; @@ -34,6 +35,7 @@ */ @Resource private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler; + @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() @@ -49,16 +51,13 @@ .and() // 配置没有权限自定义处理类 .exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler) - .and() - .csrf().disable(); - // 基于Token不需要session - http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - // 禁用缓存 - http.headers().cacheControl(); - http.addFilterBefore(new JWTAuthenticationTokenFilter(), AnonymousAuthenticationFilter.class); - - - - + .and() + .csrf().disable(); + // 基于Token不需要session + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // 禁用缓存 + http.headers().cacheControl(); + http.antMatcher("/api/applet/**").addFilterBefore(new AppletAuthenticationFilter(), AnonymousAuthenticationFilter.class); + http.addFilterBefore(new JWTAuthenticationTokenFilter(), AnonymousAuthenticationFilter.class); } } diff --git a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java new file mode 100644 index 0000000..83ae031 --- /dev/null +++ b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java @@ -0,0 +1,133 @@ +package com.panzhihua.zuul.filters; + +import com.alibaba.fastjson.JSONArray; +import com.panzhihua.common.constants.*; +import com.panzhihua.common.model.vos.R; +import com.panzhihua.common.utlis.JWTTokenUtil; +import com.panzhihua.common.utlis.ResultUtil; +import com.panzhihua.zuul.config.RealNamedConfig; +import io.jsonwebtoken.Claims; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Component; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @program: springcloud_k8s_panzhihuazhihuishequ + * @description: 小程序权限验证 + * @author: huang.hongfa weixin hhf9596 qq 959656820 + * @create: 2020-11-25 16:35 + **/ +@Component +public class AppletAuthenticationFilter implements Filter { + private StringRedisTemplate stringRedisTemplate; + + @Autowired + private RealNamedConfig realNamedConfig; + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + /** + * 用户是否登录校验 + * + * @param servletRequest 请求 + * @param servletResponse 返回 + * @param filterChain 过滤器链条 + * @throws IOException io + * @throws ServletException servlet + */ + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + SafeboxRequestWrapper safeboxRequestWrapper = new SafeboxRequestWrapper(request); + HttpServletResponse response = (HttpServletResponse) servletResponse; + + // 获取请求头中JWT的Token + String tokenHeader = request.getHeader(TokenConstant.TOKEN_HEADER); + if (null != tokenHeader && tokenHeader.startsWith(TokenConstant.TOKEN_PRE)) { + // token过期 + String token = tokenHeader.replace(TokenConstant.TOKEN_PRE, ""); + + // token解析 + Claims claims = JWTTokenUtil.getClaimsFromToken(token); + String username = claims.getSubject(); + int type = (Integer) claims.get("type"); + if (1 == type) {//小程序用户统一角色 + String requestURI = request.getRequestURI(); + String requestMethod = request.getMethod().toLowerCase(); + + ServletContext context = request.getServletContext(); + ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); + stringRedisTemplate = ctx.getBean(StringRedisTemplate.class); + ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); + String appletUserRoleKey = SecurityConstants.ROLE_APPLETS_USER + username; + Boolean userHasRole = stringRedisTemplate.hasKey(appletUserRoleKey); + + boolean needCheck = false; + List<String> checkedUrl = realNamedConfig.getVerify(); + checkedUrl = checkedUrl!=null?checkedUrl:new ArrayList<>(); + for (int i = 0; i < checkedUrl.size(); i++) { + String url = checkedUrl.get(i); + if (url.contains(requestURI) && url.toLowerCase().startsWith(requestMethod)) { + needCheck = true; + } else { + continue; + } + } + if (needCheck) { + if (userHasRole) { + boolean userHashRight = false; + try { + String roles = valueOperations.get(appletUserRoleKey); + List<SimpleGrantedAuthority> authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class); + if (authorities != null && authorities.size() > 0) { + AtomicBoolean userHasRightRole = new AtomicBoolean(false); + authorities.forEach(authority -> { + if (authority.getAuthority().equals(SecurityConstants.ROLE_APPLETS_REAL_NAMED)) { + userHasRightRole.set(true); + } + }); + if (userHasRightRole.get()) { + //用户包含“已实名”角色,则放行 什么也不做 + userHashRight = true; + } + } + } catch (Exception e) { + userHashRight = false; + } + + if (!userHashRight) { + ResultUtil.responseJson(response, R.fail(HttpStatus.FORBIDDEN, "用户未实名")); + return; + } + }else{ + ResultUtil.responseJson(response, R.fail(HttpStatus.FORBIDDEN, "用户未实名")); + return; + } + + } + } + } + filterChain.doFilter(safeboxRequestWrapper, response); + } + + @Override + public void destroy() { + + } +} diff --git a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java index 01aa7ee..e8243dd 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java +++ b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java @@ -1,176 +1,193 @@ -package com.panzhihua.zuul.filters; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.panzhihua.common.constants.*; -import com.panzhihua.common.model.vos.LoginUserInfoVO; -import com.panzhihua.common.model.vos.R; -import com.panzhihua.common.service.user.UserService; -import com.panzhihua.common.utlis.AES; -import com.panzhihua.common.utlis.JWTTokenUtil; -import com.panzhihua.common.utlis.ResultUtil; -import io.jsonwebtoken.Claims; -import org.springframework.context.ApplicationContext; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.data.redis.core.ValueOperations; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.springframework.util.ObjectUtils; -import org.springframework.web.context.support.WebApplicationContextUtils; - -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * @program: springcloud_k8s_panzhihuazhihuishequ - * @description: token校验 - * @author: huang.hongfa weixin hhf9596 qq 959656820 - * @create: 2020-11-25 16:35 - **/ -@Component -public class JWTAuthenticationTokenFilter implements Filter { - private StringRedisTemplate stringRedisTemplate; - private UserService userService; - - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - /** - * 用户是否登录校验 - * - * @param servletRequest 请求 - * @param servletResponse 返回 - * @param filterChain 过滤器链条 - * @throws IOException io - * @throws ServletException servlet - */ - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) servletRequest; - HttpServletResponse response = (HttpServletResponse) servletResponse; - ServletContext context = request.getServletContext(); - ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); - stringRedisTemplate=ctx.getBean(StringRedisTemplate.class); - ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); - userService=ctx.getBean(UserService.class); - String requestURI = request.getRequestURI(); - boolean login = requestURI.contains("login"); - boolean doc = requestURI.contains("doc.html"); - boolean css = requestURI.contains(".css"); - boolean js = requestURI.contains(".js"); - boolean ui = requestURI.contains("/ui"); - boolean swagger = requestURI.contains("swagger"); - boolean ico = requestURI.contains(".ico"); - boolean docs = requestURI.contains("-docs"); - boolean error = requestURI.contains("error"); - boolean useragreement = requestURI.contains("useragreement"); - boolean refreshToken = requestURI.contains("refreshToken"); - boolean logout = requestURI.contains("logout"); - boolean wxPay = requestURI.contains("wxNotify"); - boolean wxCgi = requestURI.contains("cgi"); - boolean isShop = requestURI.contains("isShop"); - boolean listadvertisement = requestURI.contains("listadvertisement"); - SafeboxRequestWrapper safeboxRequestWrapper = new SafeboxRequestWrapper(request); - if (login||doc||css||js||ui||swagger||ico||docs||error||refreshToken||useragreement||wxPay||wxCgi||isShop||listadvertisement) { - //什么也不做 - } else { - // 获取请求头中JWT的Token - String tokenHeader = request.getHeader(TokenConstant.TOKEN_HEADER); - if (null != tokenHeader && tokenHeader.startsWith(TokenConstant.TOKEN_PRE)) { - // token过期 - String token = tokenHeader.replace(TokenConstant.TOKEN_PRE, ""); - Boolean hasKey = stringRedisTemplate.hasKey(UserConstants.LOGOUT_TOKEN + token); - if (hasKey) { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "用户已经登出")); - return; - } - Boolean expired = JWTTokenUtil.isTokenExpired(token); - if (expired) { - if (logout) { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "登出成功")); - } else { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token过期")); - } - return; - } - // token解析 - Claims claims = JWTTokenUtil.getClaimsFromToken(token); - if (ObjectUtils.isEmpty(claims)) { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); - return; - } - String username = claims.getSubject(); - int type = (Integer) claims.get("type"); - if (ObjectUtils.isEmpty(username)) { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); - return; - } - List<SimpleGrantedAuthority> authorities = new ArrayList<>(); - List<SimpleGrantedAuthority> authorities1 = new ArrayList<>(); - String key = SecurityConstants.ROLE_USER + username; - Boolean aBoolean = stringRedisTemplate.hasKey(key); - if (1 == type) {//小程序用户统一角色 - authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_APPLETS)); - } else { - if (aBoolean) { - String roles = valueOperations.get(key); - authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class); - } else { - R<List<String>> r = userService.getUserRoles(username); - List<String> data =(List<String>)r.getData(); - if (!ObjectUtils.isEmpty(data)) { - data.forEach(s -> { - authorities1.add(new SimpleGrantedAuthority(s)); - }); - authorities = authorities1; - valueOperations.set(key, JSONArray.toJSONString(authorities), 24, TimeUnit.HOURS); - } - } - } - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, username, authorities);//主要使用权限 账户 密码 不重要 - SecurityContextHolder.getContext().setAuthentication(authentication); - safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_LOGOUT,tokenHeader); - //登录用户的所有信息 - String userKey = UserConstants.LOGIN_USER_INFO + username; - Boolean hasKeyLoginUserInfo = stringRedisTemplate.hasKey(userKey); - if(hasKeyLoginUserInfo){ - String userInfo = valueOperations.get(userKey); - byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY); - String hexStr = AES.parseByte2HexStr(encrypt); - safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO, hexStr); - }else{ - R<LoginUserInfoVO> r = userService.getUserInfoByUserId(username); - if (!R.isOk(r)) { - ResultUtil.responseJson(response, R.fail(HttpStatus.ERROR, "登录用户信息查询失败")); - return; - } - LoginUserInfoVO data = r.getData(); - String userInfo = JSONObject.toJSONString(data); - valueOperations.set(userKey,userInfo,24,TimeUnit.HOURS); - byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY); - String hexStr = AES.parseByte2HexStr(encrypt); - safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO,hexStr ); - } - } else { - ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); - return; - } - } - filterChain.doFilter(safeboxRequestWrapper,response); - } - - @Override - public void destroy() { - - } -} +package com.panzhihua.zuul.filters; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.panzhihua.common.constants.*; +import com.panzhihua.common.model.vos.LoginUserInfoVO; +import com.panzhihua.common.model.vos.R; +import com.panzhihua.common.service.user.UserService; +import com.panzhihua.common.utlis.AES; +import com.panzhihua.common.utlis.JWTTokenUtil; +import com.panzhihua.common.utlis.ResultUtil; +import io.jsonwebtoken.Claims; +import org.springframework.context.ApplicationContext; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @program: springcloud_k8s_panzhihuazhihuishequ + * @description: token校验 + * @author: huang.hongfa weixin hhf9596 qq 959656820 + * @create: 2020-11-25 16:35 + **/ +@Component +public class JWTAuthenticationTokenFilter implements Filter { + private StringRedisTemplate stringRedisTemplate; + private UserService userService; + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + /** + * 用户是否登录校验 + * + * @param servletRequest 请求 + * @param servletResponse 返回 + * @param filterChain 过滤器链条 + * @throws IOException io + * @throws ServletException servlet + */ + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + ServletContext context = request.getServletContext(); + ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); + stringRedisTemplate=ctx.getBean(StringRedisTemplate.class); + ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); + userService=ctx.getBean(UserService.class); + String requestURI = request.getRequestURI(); + boolean login = requestURI.contains("login"); + boolean doc = requestURI.contains("doc.html"); + boolean css = requestURI.contains(".css"); + boolean js = requestURI.contains(".js"); + boolean ui = requestURI.contains("/ui"); + boolean swagger = requestURI.contains("swagger"); + boolean ico = requestURI.contains(".ico"); + boolean docs = requestURI.contains("-docs"); + boolean error = requestURI.contains("error"); + boolean useragreement = requestURI.contains("useragreement"); + boolean refreshToken = requestURI.contains("refreshToken"); + boolean logout = requestURI.contains("logout"); + boolean wxPay = requestURI.contains("wxNotify"); + boolean wxCgi = requestURI.contains("cgi"); + boolean isShop = requestURI.contains("isShop"); + boolean listadvertisement = requestURI.contains("listadvertisement"); + SafeboxRequestWrapper safeboxRequestWrapper = new SafeboxRequestWrapper(request); + if (login||doc||css||js||ui||swagger||ico||docs||error||refreshToken||useragreement||wxPay||wxCgi||isShop||listadvertisement) { + //什么也不做 + } else { + // 获取请求头中JWT的Token + String tokenHeader = request.getHeader(TokenConstant.TOKEN_HEADER); + if (null != tokenHeader && tokenHeader.startsWith(TokenConstant.TOKEN_PRE)) { + // token过期 + String token = tokenHeader.replace(TokenConstant.TOKEN_PRE, ""); + Boolean hasKey = stringRedisTemplate.hasKey(UserConstants.LOGOUT_TOKEN + token); + if (hasKey) { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "用户已经登出")); + return; + } + Boolean expired = JWTTokenUtil.isTokenExpired(token); + if (expired) { + if (logout) { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "登出成功")); + } else { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token过期")); + } + return; + } + // token解析 + Claims claims = JWTTokenUtil.getClaimsFromToken(token); + if (ObjectUtils.isEmpty(claims)) { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); + return; + } + String username = claims.getSubject(); + int type = (Integer) claims.get("type"); + if (ObjectUtils.isEmpty(username)) { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); + return; + } + List<SimpleGrantedAuthority> authorities = new ArrayList<>(); + List<SimpleGrantedAuthority> authorities1 = new ArrayList<>(); + if (1 == type) {//小程序用户统一角色 + String roleAppletKey = SecurityConstants.ROLE_APPLETS_USER +username; + if(stringRedisTemplate.hasKey(roleAppletKey)){ + String roles = valueOperations.get(roleAppletKey); + authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class); + }else { + authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_APPLETS)); + String userKey = UserConstants.LOGIN_USER_INFO + username; + Boolean hasKeyLoginUserInfo = stringRedisTemplate.hasKey(userKey); + if (hasKeyLoginUserInfo) { + String userInfo = valueOperations.get(userKey); + LoginUserInfoVO loginUserInfoVO = JSONObject.parseObject(userInfo, LoginUserInfoVO.class); + //判断用户是否已实名制 + if (loginUserInfoVO.getIsRealNamed() != null && loginUserInfoVO.getIsRealNamed()) { + authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_APPLETS_REAL_NAMED)); + } + } + valueOperations.set(roleAppletKey, JSONArray.toJSONString(authorities), 24, TimeUnit.HOURS); + } + } else { + String key = SecurityConstants.ROLE_USER + username; + Boolean aBoolean = stringRedisTemplate.hasKey(key); + if (aBoolean) { + String roles = valueOperations.get(key); + authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class); + } else { + R<List<String>> r = userService.getUserRoles(username); + List<String> data =(List<String>)r.getData(); + if (!ObjectUtils.isEmpty(data)) { + data.forEach(s -> { + authorities1.add(new SimpleGrantedAuthority(s)); + }); + authorities = authorities1; + valueOperations.set(key, JSONArray.toJSONString(authorities), 24, TimeUnit.HOURS); + } + } + } + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, username, authorities);//主要使用权限 账户 密码 不重要 + SecurityContextHolder.getContext().setAuthentication(authentication); + safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_LOGOUT,tokenHeader); + //登录用户的所有信息 + String userKey = UserConstants.LOGIN_USER_INFO + username; + Boolean hasKeyLoginUserInfo = stringRedisTemplate.hasKey(userKey); + if(hasKeyLoginUserInfo){ + String userInfo = valueOperations.get(userKey); + byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY); + String hexStr = AES.parseByte2HexStr(encrypt); + safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO, hexStr); + }else{ + R<LoginUserInfoVO> r = userService.getUserInfoByUserId(username); + if (!R.isOk(r)) { + ResultUtil.responseJson(response, R.fail(HttpStatus.ERROR, "登录用户信息查询失败")); + return; + } + LoginUserInfoVO data = r.getData(); + String userInfo = JSONObject.toJSONString(data); + valueOperations.set(userKey,userInfo,24,TimeUnit.HOURS); + byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY); + String hexStr = AES.parseByte2HexStr(encrypt); + safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO,hexStr ); + } + } else { + ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败")); + return; + } + } + filterChain.doFilter(safeboxRequestWrapper,response); + } + + @Override + public void destroy() { + + } +} diff --git a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml index d8ae672..8837176 100644 --- a/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml +++ b/springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml @@ -28,5 +28,40 @@ service-url: defaultZone: http://${EUREKA_URL:localhost}:8192/eureka - - + # applet 需实名认证的接口地址 +applet: + realname: + verify: + - POST:/api/applets/house + - POST:/api/applets/putHouse + - POST:/api/applets/undercarriageHouse + - GET:/api/applets/delHouse + - POST:/api/applets/questnaire/add + - GET:/api/applets/questnaire/delete + - POST:/api/applets/questnaire/edit + - GET:/api/applets/questnaire/stat/details + - POST:/api/applets/questnaire/toggle + - POST:/api/applets/questnaire/stat/answer + - POST:/api/applets/index/comacteasyphotocomment + - POST:/api/applets/index/commentsign + - POST:/api/applets/index/addmessageback + - POST:/api/applets/index/addmessage + - POST:/api/applets/index/easyphoto + - PUT:/api/applets/index/easyphoto + - POST:/api/applets/index/microwish + - PUT:/api/applets/index/microwish + - POST:/api/applets/discuss + - POST:/api/applets/discusscommentback + - PUT:/api/applets/discusscommentuser + - POST:/api/applets/discussuser + - POST:/api/applets/neighbor/addNeighborByApp + - POST:/api/applets/neighbor/cancel/fabulous + - POST:/api/applets/neighbor/comment + - POST:/api/applets/neighbor/fabulous + - POST:/api/applets/neighbor/reply + - PUT:/api/applets/community/signactivity + - POST:/api/applets/community/volunteer + - POST:/api/applets/user/houses + - POST:/api/appletsbackstage/common/data/car/save + - DELETE:/api/appletsbackstage/common/data/car/delete + - POST:/api/applets/community/car/register \ No newline at end of file -- Gitblit v1.7.1