zrj
2024-06-11 4069aa1d01bb4ce98ea154940a46d5c014252897
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package org.springblade.auth.handle;
 
import com.alibaba.nacos.common.utils.StringUtils;
import io.jsonwebtoken.Claims;
import org.springblade.core.jwt.JwtUtil;
import org.springblade.core.launch.constant.TokenConstant;
import org.springblade.core.secure.registry.SecureRegistry;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.List;
 
/**
 * token 校验过滤器
 */
@Configuration
public class TokenFilterHandle extends OncePerRequestFilter {
 
    /**
     * 安全框架配置
     */
    @Bean
    public SecureRegistry secureRegistry() {
        SecureRegistry secureRegistry = new SecureRegistry();
        secureRegistry.setEnabled(true);
        secureRegistry.excludePathPatterns("/oauth/login");
        secureRegistry.excludePathPatterns("/oauth/authorize");
        secureRegistry.excludePathPatterns("/oauth/form");
        secureRegistry.excludePathPatterns("/oauth/token");
        secureRegistry.excludePathPatterns("/blade-system/menu/routes");
        secureRegistry.excludePathPatterns("/blade-system/menu/auth-routes");
        secureRegistry.excludePathPatterns("/blade-system/menu/top-menu");
        secureRegistry.excludePathPatterns("/blade-system/tenant/info");
        secureRegistry.excludePathPatterns("/blade-flow/process/resource-view");
        secureRegistry.excludePathPatterns("/blade-flow/process/diagram-view");
        secureRegistry.excludePathPatterns("/blade-flow/manager/check-upload");
        secureRegistry.excludePathPatterns("/doc.html");
        secureRegistry.excludePathPatterns("/js/**");
        secureRegistry.excludePathPatterns("/webjars/**");
        secureRegistry.excludePathPatterns("/swagger-resources/**");
        secureRegistry.excludePathPatterns("/druid/**");
        return secureRegistry;
    }
 
 
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        // 白名单url 放行
        if (filterWhiteUrl(requestURI)){
            filterChain.doFilter(request, response);
            return;
        }
 
        // 获取请求头
        String auth = request.getHeader("Blade-Auth");
        if (StringUtils.isBlank(auth)) {
            // 无授权处理
            unAuthResponse(response);
            return;
        }
 
        String token = JwtUtil.getToken(auth);
        Claims claims = JwtUtil.parseJWT(token);
        if (!StringUtils.isBlank(token) && null!=claims) {
            //判断 Token 状态
            String tenantId = String.valueOf(claims.get(TokenConstant.TENANT_ID));
            String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
            String account = String.valueOf(claims.get(TokenConstant.ACCOUNT));
            String accessToken = JwtUtil.getAccessToken(tenantId, userId, token);
            if (token.equalsIgnoreCase(accessToken)) {
                UsernamePasswordAuthenticationToken authenticationToken
                    = new UsernamePasswordAuthenticationToken(account, null);
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }else {
            // 无授权处理
            unAuthResponse(response);
            return;
        }
 
        filterChain.doFilter(request, response);
    }
 
    /**
     * 白名单url 放行
     * @param requestURI
     * @return
     */
    private boolean filterWhiteUrl(String requestURI) {
        List<String> whiteList = secureRegistry().getExcludePatterns();
        if (CollectionUtil.isNotEmpty(whiteList)) {
            PathMatcher matcher = new AntPathMatcher();
            for (String releaseUrl : whiteList) {
                boolean match = matcher.match(releaseUrl, requestURI);
                if (match) {
                    return true;
                }
            }
        }
        return false;
    }
 
    /**
     * 无授权处理
     * @param response
     * @throws IOException
     */
    private void unAuthResponse(HttpServletResponse response) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
        writer.write("{\"status\": 401,\n" + "\"error\": \"Unauthorized\"\n" + "}");
        writer.flush();
    }
}