spring security如何绕过指定域名的安全认证

我使用基于jwt令牌的spring security。我有一个端点/sample-endpoint,需要认证。

然而,当请求来自一个叫xyz.com的特定域名时候,我需要绕过这个端点的认证。

这可以实现吗?应该怎么实现?

我目前的配置

SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

// cant add the end point here as it would open up for everybody.
public static final String[] unauthedUrls = { "healthcheck","some-other-endpoint"}  

@Override
    protected void configure(HttpSecurity http) throws Exception {
        
        http
                .httpBasic()
                .disable()
                .csrf()
                .disable()
                .cors()
                .and()
                .headers().frameOptions()
                .disable()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and()
                .addFilterAfter(jwtSecurityFilter, UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                .antMatchers(unauthedUrls)
                .permitAll()
                .anyRequest()
                .authenticated();
    }

JwtSecurityFilter的实现

public class JwtSecurityFilter extends OncePerRequestFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(JwtSecurityFilter.class);

    private static final String JWT_PREFIX = "Bearer ";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        setAuthenticationContext(request);

        chain.doFilter(request, response);
    }

    private void setAuthenticationContext(HttpServletRequest request) {
        try {
            String token = getJwt(request);

            if (StringUtils.isBlank(token)) {
                throw new RuntimeException("Authorization token not provided");
            }

 

// some logic here...
        } catch (Exception ex) {
      
            if (request != null && Arrays.stream(SecurityConfig.unauthedUrls).anyMatch(url -> request.getRequestURI().contains(url))) {
                // it's a URL that isn't authenticated so an exception here is normal
                // if we couldn't get a token
                return;
            }
            LOGGER.warn("Unable to authenticate request: {} {}", ex.getMessage(), request == null ? null : request.getRequestURI());
        }
    }

    private String getJwt(HttpServletRequest request) {

        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);

        if (StringUtils.isBlank(authHeader) || !authHeader.startsWith(JWT_PREFIX)) {
            return "";
        }

        return authHeader.replaceFirst(Pattern.quote(JWT_PREFIX), "");
    }
}



StackOverflow:java - How to bypass spring security on an authenticated endpoint for specific domain? - Stack Overflow

jwt那你用了spring cloud oauth2没有,用了的话,应该明白spring cloud gateway作为oauth2的客户端,而其他的服务是resource server,对于resource server,会配置解析jwt的方法,这样authentication 就能取到你解析出来的对象,对象中有发送方的client_id,可以使用client_id确定权限,如果你不是使用的这一套路,就是野路子了,代码写死就完了呗

2 个赞

这么配置也不是不行,确实路子有点野。spring security5 提供的oauth2的dsl配置方式,jwt 很多都是现成的,只需要配置一些核心参数,扩展性比自己写强很多。使用异常处理来判断,如果没登录就走自己的登录流程,这确实不是上策,虽然我也是这么干的。如果要放行,让其在登录过程中不抛出异常即可,配置webSecurity.ignoring.ant,或者 在httpSecurity.antmatch().permitAll就行了。

1 个赞