Spring WebSecurityConfigurerAdapter allow POST? - java

I would like to enable POST request for a certain "/interface" URL on my site. I have successfully loaded the class via Class<?>[] getRootConfigClasses(), the specified CSP header for the HttpSecurity http exist.
Whenever I make a request to /interface, I get HTTP 403.
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests().antMatchers(HttpMethod.POST, "/interface").permitAll().and()
.headers()
.contentTypeOptions().and()
.cacheControl().and()
.httpStrictTransportSecurity().and()
.frameOptions().and()
.contentSecurityPolicy("the csp header. it is present on every response.");
}
}

Try overriding another configuration method: configure(WebSecurity webSecurity).
#Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers(POST, "/interface");
}

Related

spring security, and basic auth only one entryPoint : how manage error on the other endpoint

I need to add a basic auth in only one of my controller method
Other method don't have an auth, but still have a #PreAuthorize in order to check if the parameters are valid.
My issue is , httpbasic transform all the exception throwed by preAuthorize in 401 ( some should be 403, etc).
I have the feeling that all my endpoint are under a basic auth, not just the ones I have use #Secured
How can I avoid that?
My code:
#Controller
class MyController {
#Secured("BASIC_AUTHENTIFIED")
public void someMethodOnlyForAuthentified(){...}
#PreAuthorize("check(parameters)")
public void someMethodForEveryone(List<String> parameters){...}
}
And in my security config:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(login).password(password).roles("BASIC_AUTHENTIFIED");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.authorizeRequests().antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.and().csrf().disable();
}

JWT authentication with fallback to SAML2 for the same path

I'm using spring-security-saml2-service-provider for authentication in one of my spring boot applications and I'm using a custom JwtAuthorizationFilter (via a http Authentication header) in a different spring boot application.
They both work perfectly on their own.
Now I need to write a spring boot application that uses both of them. If the JWT token is available (Authentication header), then use the JwtAuthorizationFilter, otherwise use saml2Login.
The SAML2 configuration looks like this: (There is no filter, just the saml2Login)
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/saml2/service-provider-metadata/**").permitAll()
.antMatchers("/**").authenticated().and()
// use SAML2
.saml2Login()
.addObjectPostProcessor(new ObjectPostProcessor<OpenSamlAuthenticationProvider>() {
public <O extends OpenSamlAuthenticationProvider> O postProcess(O samlAuthProvider) {
samlAuthProvider.setAuthoritiesExtractor(authoritiesExtractor());
samlAuthProvider.setAuthoritiesMapper(authoritiesMapper());
return samlAuthProvider;
}
})
;
}
The JWT configuration looks like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/**").authenticated().and()
// use JWT
.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUtil))
;
}
I think I need something like a JwtOrSaml2AuthenticationFilter but don't know how to do that.
The solution is to
Duplicate the configuration with #Order and
Set a header based requestMatcher before the addFilter
#EnableWebSecurity
public class SecurityConfiguration {
#Order(100) // lower number = higher priority
#Configuration
#RequiredArgsConstructor
public static class AppSecurityJWT extends WebSecurityConfigurerAdapter {
final JWTUtil jwtUtil;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/saml2/service-provider-metadata/**", "/idm-app/**").permitAll()
.antMatchers("/**").authenticated().and()
// This configuration will only be active if the Authorization header is present in the request
.requestMatcher(new RequestHeaderRequestMatcher("Authorization")).addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUtil))
;
}
}
#Order(101)
#Configuration
#RequiredArgsConstructor
public static class AppSecuritySAML2 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/saml2/service-provider-metadata/**", "/idm-app/**").permitAll()
.antMatchers("/**").authenticated().and()
// This whole configuration will only be active, if the previous (100) didn't match
.saml2Login()
//...
;
}
}

How to open an endpoint to everyone?

I am implementing OAuth2 in my App. The problem is that I want to open some endpoints to make them accessible without any authentication or role. The file that is giving problems is this: (I want to open an endpoint that is "/api/someRoute/parameters")
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests().antMatchers("/api/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')")
.and()
.exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
} ```
This should work -
.authorizeRequests().antMatchers("/api/someRoute/parameters").permitAll()

Spring Boot 2 security - pre-authenticated token - allow healthcheck

My Spring Boot Actuator healthCheck is blocked because of a (pre_authenticated) token is missing.
There are many answers available, BUT this is question has interference with pre-authenticated security. As far as I searched, this is NOT a duplicate.
How can I allow the health check in a pre-authenticated security environment?
My question is also, do I need more settings (in e.g. the application.properties)?
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new XyzPreAuthenticatedGrantedAuthoritiesUserDetailsService());
auth.authenticationProvider(provider);
}
// Try-1, see below
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(xyzTokenRequestHeaderAuthenticationFilter(), RequestHeaderAuthenticationFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated();
}
#Bean
public XyzTokenRequestHeaderAuthenticationFilter xyzTokenRequestHeaderAuthenticationFilter() throws Exception {
XyzTokenRequestHeaderAuthenticationFilter filter = new XyzTokenRequestHeaderAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager());
return filter;
}
}
My second try was:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(xyzTokenRequestHeaderAuthenticationFilter(), RequestHeaderAuthenticationFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll();
}
It looks like the xyz filter is not implemented in the 'perfect' way.
This way will help you get things workin':
1 - use the management port:
management.server.port=8081
management.security.enabled=false
management.server.address=127.0.0.1
management.server.ssl.enabled=false
management.endpoints.health.sensitive=false
management.endpoint.health.show-details=always
2 - configure both ways web and api. Use this beyond the standard parts:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(STATELESS);
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/**").authenticated();
http.addFilterBefore(xyzTokenRequestHeaderAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/actuator/**");
}
3 - Inside the Docker container, use the 8081 port for the healthCheck.
Try to add in .ignoring() and add #EnableGlobalMethodSecurity(prePostEnabled = true), #Configuration at class
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer{
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/actuator/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(xyzTokenRequestHeaderAuthenticationFilter(), RequestHeaderAuthenticationFilter.class);
}
}
The problem seems to be with your XyzTokenRequestHeaderAuthenticationFilter implementation. If you wrote that by extending RequestHeaderAuthenticationFilter, then you must set the property exceptionIfHeaderMissing to false.
If you didn't extend that Spring Security pre auth core class then you need to show the implementation.

Dynamically Configure LDAP Server using Spring Security

The Spring Security Tutorial has an example of configuring an LDAP Server:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
#Configuration
protected static class AuthenticationConfiguration extends
GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource().ldif("classpath:test-server.ldif");
}
}
}
However, I'm looking for a way to initialize the the LDAP server dynamically, not in the configuration file. I can't seem to find any examples. The purpose of this is to implement SSO for a login form.
I found it easier to work with a lower-level directory, ldaptive, to solve this problem.

Categories

Resources