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 { //未通过发通知 /** 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:";//小程序用户角色 } 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); } springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java
New file @@ -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; } 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() @@ -55,10 +57,7 @@ http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 禁用缓存 http.headers().cacheControl(); http.antMatcher("/api/applet/**").addFilterBefore(new AppletAuthenticationFilter(), AnonymousAuthenticationFilter.class); http.addFilterBefore(new JWTAuthenticationTokenFilter(), AnonymousAuthenticationFilter.class); } } springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java
New file @@ -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() { } } springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java
@@ -117,11 +117,28 @@ } 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 (1 == type) {//小程序用户统一角色 authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_APPLETS)); } else { if (aBoolean) { String roles = valueOperations.get(key); authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class); 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