liyanqi
2022-09-10 dbf345c90bc8d48f600d1b8e429cd4e9332f906b
解决因spring security导致的无法跨域问题
6个文件已修改
1个文件已添加
1个文件已删除
112 ■■■■■ 已修改文件
ycl-common/src/main/java/com/ycl/api/BasePageVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/config/GlobalCorsConfig.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/config/WebSecurityCorsFilter.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/utils/JwtTokenUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/utils/auth/UserAuthUtil.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/java/com/ycl/component/JwtAuthenticationTokenFilter.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/java/com/ycl/config/SecurityConfig.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/api/BasePageVO.java
@@ -16,7 +16,7 @@
    @Min(value = 1, message = "最小页数1")
    private int current = 1;
    @ApiModelProperty(value = "条数",example = "1~100")
    @ApiModelProperty(value = "条数",example = "1")
    @Min(value = 1, message = "最小条数1")
    @Max(value = 100, message = "最大条数100")
    private int pageSize = 20;
ycl-common/src/main/java/com/ycl/config/GlobalCorsConfig.java
File was deleted
ycl-common/src/main/java/com/ycl/config/WebSecurityCorsFilter.java
New file
@@ -0,0 +1,41 @@
package com.ycl.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
/**
 * @author Lyq
 * @version 1.0
 * @date 2022/9/10 1:04
 */
public class WebSecurityCorsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control, os, version, source");
        chain.doFilter(request, res);
    }
    @Override
    public void destroy() {
    }
}
ycl-common/src/main/java/com/ycl/utils/JwtTokenUtil.java
@@ -96,7 +96,7 @@
     * @param userDetails 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, UserDetails userDetails) {
        String username = getUserNameFromToken(token);
        String username = parseToken(token).getUsername();
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }
ycl-common/src/main/java/com/ycl/utils/auth/UserAuthUtil.java
@@ -8,6 +8,7 @@
import com.ycl.utils.JwtTokenUtil;
import com.ycl.utils.common.LiveTimeMillisecond;
import com.ycl.utils.common.NetworkUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -25,6 +26,8 @@
    @Resource
    private RedisService redisService;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    public void saveUser(Long userId, String token, String redisKey) {
        redisService.set(redisKey.concat(userId.toString()), token, LiveTimeMillisecond.s2592000.time);
@@ -41,7 +44,8 @@
        if (StrUtil.isBlank(accessToken)) {
            throw new ApiException(ResultCode.NOT_LOGGED);
        }
        AuthInfo authInfo = jwtTokenUtil.parseToken(accessToken);
        String authToken = accessToken.substring(this.tokenHead.length());// The part after "Bearer "
        AuthInfo authInfo = jwtTokenUtil.parseToken(authToken);
        return authInfo.getUserId();
    }
@@ -56,7 +60,9 @@
        if (StrUtil.isBlank(accessToken)) {
            throw new ApiException(ResultCode.NOT_LOGGED);
        }
        AuthInfo authInfo = jwtTokenUtil.parseToken(accessToken);
        String authToken = accessToken.substring(this.tokenHead.length());// The part after "Bearer "
        AuthInfo authInfo = jwtTokenUtil.parseToken(authToken);
//        AuthInfo authInfo = jwtTokenUtil.parseToken(accessToken);
        return authInfo.getUsername();
    }
}
ycl-platform/src/main/java/com/ycl/component/JwtAuthenticationTokenFilter.java
@@ -1,5 +1,6 @@
package com.ycl.component;
import com.ycl.entity.auth.AuthInfo;
import com.ycl.utils.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,6 +18,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
 * JWT登录授权过滤器
@@ -36,13 +38,19 @@
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        System.out.println(request);
//        Enumeration<String> headerNames = request.getHeaderNames();
//        while (headerNames.hasMoreElements()){
//            System.out.println(headerNames.nextElement());
//        }
        String authHeader = request.getHeader(this.tokenHeader);
        if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
            String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            AuthInfo authInfo = jwtTokenUtil.parseToken(authToken);
            String username = authInfo.getUsername();
            LOGGER.info("checking username:{}", username);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(authInfo.getUsername());
                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
ycl-platform/src/main/java/com/ycl/config/SecurityConfig.java
@@ -63,11 +63,17 @@
                .authenticationEntryPoint(restAuthenticationEntryPoint)
                // 自定义权限拦截器JWT过滤器
                .and()
                .addFilterBefore(webSecurityCorsFilter(), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //有动态权限配置时添加动态权限校验过滤器
        if(dynamicSecurityService!=null){
        if (dynamicSecurityService != null) {
            registry.and().addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class);
        }
        return httpSecurity.build();
    }
    @Bean
    public WebSecurityCorsFilter webSecurityCorsFilter() {
        return new WebSecurityCorsFilter();
    }
}
ycl-platform/src/main/resources/application.yml
@@ -28,7 +28,7 @@
jwt:
  tokenHeader: Authorization #JWT存储的请求头
  secret: luozi-admin-secret #JWT加解密使用的密钥
  secret: platform-secret #JWT加解密使用的密钥
  expiration: 604800 #JWT的超期限时间(60*60*24*7)
  tokenHead: 'Bearer ' #JWT负载中拿到开头