0

I am using jwt token based spring security. I have an endpoint '/sample-endpoint' which requires authentication. However, I need to bypass security for this endpoint when the request comes from a specific domain called xyz.com.

Is it possible to do so? If so, how to do that?

Here is what I have so far.

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();
    }

Here is JwtSecurityFilter implementation.

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), "");
    }
}


K17
  • 1
  • 1
  • 1
  • Welcome to SO. Maybe you could create a custom expression handler to check the HttpServletRequest. something like `.expressionHandler(new CustomDomainCheckExpressionHandler()).anyRequest().access("isDomainWhitelisted()")` – Ritesh Jun 24 '21 at 10:27

1 Answers1

0

What you want is to ignore certain URLs for this override the configure method that takes WebSecurity object and ignores the pattern. For example, using the api:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/v1/signup");
}

And remove that line from the HttpSecurity part. This will tell Spring Security to ignore this URL and don't apply any filters to them.

I have a better way:

http
    .authorizeRequests()
    .antMatchers("/api/v1/signup/**").permitAll()
    .anyRequest().authenticated()
troy
  • 76
  • 3
  • This would open up this endpoint for all. I want to keep that endpoint closed for all and just open up for a specific domain. – K17 Jun 24 '21 at 02:44
  • 1
    Also, please dont copy paste answers from other posts. https://stackoverflow.com/questions/30366405/how-to-disable-spring-security-for-particular-url – K17 Jun 24 '21 at 03:07
  • @troy Welcome to SO. See the inbuilt expression such as `hasIpAddress`. See [Web Security Expressions](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-access-web). We need something like that here to check the request domain/host. – Ritesh Jun 24 '21 at 10:37