Spring security: avoid authorization and authentication for certain paths - spring-boot

This is my related spring security configuration:
#Bean
SecurityWebFilterChain springSecurityFilterChain(
ServerHttpSecurity http,
AuthenticationWebFilter authenticationWebFilter
) {
return http
.httpBasic(HttpBasicSpec::disable)
.csrf(CsrfSpec::disable)
.formLogin(FormLoginSpec::disable)
.anonymous(AnonymousSpec::disable)
.logout(LogoutSpec::disable)
.authorizeExchange((authorize) -> authorize
.pathMatchers("/actuator/**").permitAll()
.pathMatchers("/login/**").permitAll()
.anyExchange().authenticated()
)
.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
.build();
}
#Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/actuator/**", "/login/**");
}
As you can see, I'm setting an AuthenticationWebFilter at SecurityWebFiltersOrder.AUTHENTICATION level.
I'm also avoiding to authorize "/actuator/**" and "/login/**" paths and I'm avoiding authentication for using WebSecurityCustomizer.
However, when I'm trying to reach above paths, I see authentication process is launched for above paths since, authenticationFilter is reached at code.
How could avoid authorization and authentication only for "/actuator/**" and "/login/**"?
EDIT:
I've took a look on this question, but its approach is what I'm using exactly with WebSecurityCustomizer...

Related

Spring security very simple basic authentication

I've tried to implement a very simple BASIC authentication with Spring Boot, without the deprecated WebSecurityConfigurerAdapter.
#Configuration
public class SecurityConfig {
#Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/a", "/b", "/c", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
#Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.builder()
.username("user")
.password("{bcrypt}$2y$10$rUzpfbTx9lcIs6N4Elcg2e2DGM4wMwkx0ixom7qLW5kYnztRgT.a2")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
The ignored endpoints work (with a warning: You are asking Spring Security to ignore Ant [pattern='/swagger-ui.html']. This is not recommended -- please use permitAll via HttpSecurity#authorizeHttpRequests instead.). For the other, I get an HTTP 403.
What have I done wrong?
If you are doing POST request, it can be the CSRF protection. Add logging.level.org.springframework.security=TRACE in your application.properties file and see the console output after the request is made to see what is happening.
If it is CSRF protection, I recommend you leave it enabled unless you have a requirement that tells you to disable it. You can have more details about Cross Site Request Forgery here.
Also, if you want to use the {bcrypt} prefix in your password, use the PasswordEncoderFactories.createDelegatingPasswordEncoder. If you want to use only the BCryptPasswordEncoder then you have to remove the {bcrypt} prefix

Can mutual auth and x509 co exist in same spring boot application?

I'm running two jvms. One with webapp jwt auth and another one for mutual auth. It creates lot of overhead to the hosting machine? Is it possible to auth different paths with different auth mode in spring?
Yes, you can use multiple filter chains, one for each path:
#Bean
#Order(0)
SecurityFilterChain jwtPaths(HttpSecurity http) throws Exception {
http
.requestMatchers((requests) -> requests.mvcMatchers("/jwt-paths/**"))
// configuration for paths that use JWT auth
return http.build();
}
#Bean
#Order(1)
SecurityFilterChain x509Paths(HttpSecurity http) throws Exception {
http
.requestMatchers((requests) -> requests.mvcMatchers("/x509Paths/**"))
// configuration for paths that use X.509 auth
return http.build();
}

Spring Security Configuration: Basic Auth + Spring Cloud Gateway

I've got a Reactive Spring Boot application, which is responsible for routing requests to downstream services, using Spring Cloud Gateway (i.e. it's an API gateway). The app has some actuator endpoints, that need to be secured, hence I want to use just a simple security for this like basic auth.
I'd like to configure the app, to require requests to /actuator/refresh to be authorized using basic auth (with a configured Spring security user and password). All requests to other endpoints, even if they include basic auth, only need to be passed to the downstream service.
My current Spring security configuration:
#Bean
#Order(1)
SecurityWebFilterChain securityWebFilterChain(final ServerHttpSecurity http) {
http.authorizeExchange(exchanges -> {
exchanges.matchers(EndpointRequest.toAnyEndpoint().excluding(HealthEndpoint.class, InfoEndpoint.class)).hasRole("ACTUATOR"); // requires Http Basic Auth
});
http.httpBasic(withDefaults()); // if not enabled, you cannot get the ACTUATOR role
return http.build();
}
#Bean
#Order(2)
SecurityWebFilterChain permitAllWebFilterChain(final ServerHttpSecurity http) {
http.authorizeExchange(exchanges -> exchanges.anyExchange().permitAll()); // allow unauthenticated access to any endpoint (other than secured actuator endpoints?)
http.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable); // disable Http Basic Auth for all other endpoints
return http.build();
}
The request meant for the downstream service is not propagated by the API gateway. The spring boot service returns a 401 in this setup, while a 200 is expected / required.
Any ideas why this configuration is not working / how it should be configured otherwise?
Im not sure what is broken, but have you tried combining them and just have one filter?
#EnableWebFluxSecurity
public class MyExplicitSecurityConfiguration {
#Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("ACTUATOR")
.build();
return new MapReactiveUserDetailsService(user);
}
#Bean
SecurityWebFilterChain securityWebFilterChain(final ServerHttpSecurity http) {
http.authorizeExchange(exchanges -> {
exchanges.matchers(EndpointRequest.toAnyEndpoint()
.excluding(HealthEndpoint.class, InfoEndpoint.class))
.hasRole("ACTUATOR");
exchanges.anyExchange().permitAll();
}).httpBasic(withDefaults());
return http.build();
}
}
another good thing could be to enable debug logging and see what fails.
this is done by defining in application.properties
logging.level.org.springframework.security=DEBUG

Reactive-Spring-Security-5.1.3.RELEASE, multiple authorizations

We have some endpoints, that are secured and before to access them we're verifying that the jws is correctly. In order to do that, we've defined a SecurityContext that actually persist the Auth pojo and to manipulate it downstream into the controller. The SecurityWebFilterChain config looks like that:
#Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http.csrf().disable()
.formLogin().disable()
.logout().disable()
.httpBasic().disable()
.securityContextRepository(securityContext)
.authorizeExchange()
.anyExchange().authenticated()
.and()
.build();
}
The calls were internally made, and we just verified the jws token.
Right now some external clients need to integrate with us, and we need to verify a jwe token. The thing is, that somehow we need to tell spring-security to validate for the existent endpoints the jws and for the new one the jwe.
I tried by specifying multiple security matchers but it failed :( . Do you have any other suggestions ?
You can expose more than one bean. I recommend specifying an order:
#Bean
#Order(1)
public SecurityWebFilterChain first(ServerHttpSecurity http) {
http
.securityMatcher(...)
...
return http.build();
}
#Bean
#Order(2)
public SecurityWebFilterChain second(ServerHttpSecurity http) {
http
.securityMatcher(...)
...
return http.build();
}
As a side note, Spring Security does ship with support for verifying JWS tokens reactively, and you might be able to remove some boilerplate by using it.

Spring Boot 2.0 web flux custom authentication -- how to?

There are plenty of examples of minimal configurations of Spring Boot 2.0 security which compile or don't depending on which milestone or release candidate you try.
What is a minimal configuration that is not HTTP Basic, that will (1) let me access the HTTP request (headers, cookies, etc.) and also call my own authentication manager?
I would like to look at the headers and cookies, and decide from those who the user is, and whether or not the user is authenticated. How I do that should not matter to this answer -- the question is, what is the minimal Spring security config in order to allow me to hook in to the security infrastructure, so that my authentication is there in the reactive endpoints?
EDIT:
This works with Spring Boot 2.0.0.RC2, so my question could be, is this a correct way to introduce custom authentication into Spring Security?
#Configuration
#EnableWebFluxSecurity
public class SecurityConfiguration {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authentication -> {
authentication.setAuthenticated(true);
return Mono.just(authentication);
});
authenticationFilter.setAuthenticationConverter(serverWebExchange ->
Mono.just(new AbstractAuthenticationToken(new ArrayList<>()) {
#Override
public Object getCredentials() {
return null;
}
#Override
public Object getPrincipal() {
return "jim";
}
}));
return http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN)
.authorizeExchange()
.anyExchange()
.authenticated()
.and()
.build();
}
}
You can imagine that in the converter, I am free to look into the request by way of serverWebExchange and inspect any headers or cookies I wish, and that later in the upper lambda (standing in for ReactiveAuthenticationManager) I can actually decide whether or not it should be authenticated.

Resources