Skip to content
This repository has been archived by the owner on May 31, 2022. It is now read-only.

Skip unprotected url (http.authorizeRequests().antMatchers("url").permitAll()) from Authorization bearer validation #947

Closed
youssefguenoun opened this issue Jan 11, 2017 · 13 comments
Assignees

Comments

@youssefguenoun
Copy link

Hi

I'm using spring security oauth2 in my project.
I am excluding some urls from authentication as follow : http.authorizeRequests().antMatchers("an_unprotected_url").permitAll()

Now, what I am having is that, if I don't pass the Authorization header to the above urls, it is not authenticated. And the API is called properly.
If the call is made with an Authorization header, then it validates the token and fails the call if the token is not validated.

What do I need to do so that the token is ignored in the request for which I have permitAll.

Best regards
Youssef

@jgrandja
Copy link
Contributor

@youssefguenoun Why do you need to set the Authorization header when calling unprotected resources? This doesn't make sense to me. You should only set the Authorization header when calling a protected resource.

@BeamLiu
Copy link

BeamLiu commented Feb 28, 2018

I have similar issue, here is the autentication application configuration:

	public void configure(final HttpSecurity http) throws Exception {
		// permt "/public/**"
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		http.csrf().disable();
		http.authorizeRequests().antMatchers("/authentication/public/**").permitAll();
		http.authorizeRequests().anyRequest().authenticated();
	}

we record the access token in browser cookie, there is a gateway application before the authentication application, the gateway will pick up the access token from cookie, and set it to Authorization header when forwarding the rquest, the gateway don't know whether the forwarding url is protected, current behavior is: when the token is expired, the unprotected resources(such as /authentication/public/login) are not available when the browser cookie is still present.

Or is there a way to totally disable the spring security for some particular urls when configuring through ResourceServerConfigurerAdapter

@NameYoung
Copy link

Same problem.
Have you found a solution? @BeamLiu .

@habibrehmansg
Copy link

Same problem. Anyone found a solution?

@imranasif
Copy link

try this :

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

@mpryahin
Copy link

@youssefguenoun Why do you need to set the Authorization header when calling unprotected resources? This doesn't make sense to me. You should only set the Authorization header when calling a protected resource.

Fair enough, but having a public API exposed to the internet it's not always possible to convince all the clients to build proper HTTP requests. From the security configuration perspective if an endpoint is configured as unsecured then there is no reason to validate Authorization headers for that endpoint whatsoever.

@youssefguenoun
Copy link
Author

@mpryahin I totally agree with you, But spring security (in any case the version i've used in 2017) doesn't behave that way ! if it detect an Authorization header, it automatically validate it.

Anyway it wasn't really an issue, in our case the real issue came from some API client-code which filled an Authorization bearer header even if the API endpoint was not secured !
I just needed to understand the design principle behind this behaviour and Indeed there is NO need to set the Authorization header when calling unprotected resources !

PS : If we share the same understanding, you guys, we can now close this issue :)

Cheers,
Youssef

@mpryahin
Copy link

@youssefguenoun Yes, but before closing the issue, will we acknowledge that it's ok for external clients which are out of our control to be able to affect the behaviour of the backend application?
I've just come across the same case when a misconfigured client app was unable to access an unsecured endpoint just because of sending an extra HTTP header, consequently, making this exact endpoint secured.
Cheers, Mike.

@youssefguenoun
Copy link
Author

@mpryahin it's annoying indeed, I understand !
@jgrandja and spring security team what do you think ? please advise us
Rgds

@jgrandja jgrandja self-assigned this Jan 15, 2019
@jgrandja
Copy link
Contributor

jgrandja commented Jan 15, 2019

Thanks for your input @imranasif !

@mpryahin @youssefguenoun Have you tried the solution that @imranasif suggested in this comment? This is exactly what you need to do to disable security for specific endpoints.

For example:

@EnableWebSecurity
public class WebSecurityUnprotected extends WebSecurityConfigurerAdapter {
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().mvcMatchers("/unprotected1", "/unprotected2", "/unprotected3");
	}
}

I'm going to close this issue as answered. If you are still having an issue we can re-open.

@vlad-bura
Copy link

@jgrandja Thanks for involvement. But with EnableWebFluxSecurity this is not possible. How this should be apply there?

@Tahir52
Copy link

Tahir52 commented Mar 30, 2021

For WebFlux, I found this to do the job:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    return http.securityMatcher(new NegatedServerWebExchangeMatcher(ServerWebExchangeMatchers.pathMatchers("/ignore/this/path")))
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .csrf().disable()
                .build();
}

@MisterCool
Copy link

MisterCool commented Dec 20, 2021

Solution for webflux. Url with prefix admin is protected. Rest of urls are permit regardless of authorization header.

SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.securityMatcher(new JWTHeadersExchangeMatcher())
            .csrf().disable()
            .httpBasic().disable()
            .authorizeExchange()
            .pathMatchers("/admin/**").hasAuthority("admin")
            .anyExchange().permitAll()
            .and()
            .oauth2ResourceServer()
            .jwt()
            .jwtAuthenticationConverter(grantedAuthoritiesExtractor());

    return http.build();
}

    private static class JWTHeadersExchangeMatcher implements ServerWebExchangeMatcher {

    @Override
    public Mono<ServerWebExchangeMatcher.MatchResult> matches(final ServerWebExchange exchange) {
        Mono<ServerHttpRequest> request = Mono.just(exchange).map(ServerWebExchange::getRequest);

        return request.map(ServerHttpRequest::getPath)
                .filter(requestPath -> requestPath.value().startsWith("/admin"))
                .flatMap(requestPath -> MatchResult.match())
                .switchIfEmpty(MatchResult.notMatch());
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

10 participants