CeDo
2021-05-01 a7d2d03fe177a58c22e960e9c87b32f7b05be74f
add:添加小程序实名认证接口过滤(部分)
6个文件已修改
2个文件已添加
233 ■■■■■ 已修改文件
springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/UserApi.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/SecurityConstants.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/service_user/src/main/java/com/panzhihua/service_user/service/impl/UserServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/RealNamedConfig.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/config/SpringSecurityConfig.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/AppletAuthenticationFilter.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/java/com/panzhihua/zuul/filters/JWTAuthenticationTokenFilter.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
springcloud_k8s_panzhihuazhihuishequ/zuul/src/main/resources/bootstrap.yml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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