Spring security protect logout url - spring

I am using spring security in my project. I configure secured endpoints, using #PreAuthorize annotation. I want spring security to protect the logout URL, which I specified in the config file.
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(LOGOUT_URL).authenticated()
.anyRequest().permitAll()
.and()
.logout()
.logoutUrl(LOGOUT_URL)
.invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler);
}
Here I permit any request, except logout. I guess that this configuration is only for #RestController endpoints. But how to configure it to forbid not authenticated users to use logout.

Related

How does one use different session creation policies for UI and REST endpoints with Spring Security?

I have an application that contains both a UI and some REST endpoints. The UI uses SAML login (the old Spring Security SAML extension) and the REST endpoints using a custom authentication. The REST endpoints are only called by external applications.
For the REST endpoints ("/api/**") I have stated a stateless session creation policy and for the rest of the endpoint no session creation policy at all (I also tried with ALWAYS as in the below example).
Prior to some Spring Boot version, not sure which, this worked. Currently I'm using Spring Boot v.2.6.1. The UI endpoint got the authentication object from the Http session.
But now it doesn't work. The security context object cannot be found in the Http session using the default HttpSessionSecurityContextRepository implementation. It is saved but it can't be restored.
So is it possible to use two session creation policy, one for the REST and the other for the UI part, or should this be handled in a different way?
Now it seems that the stateless session creation policy is also used by the UI, which is not intended.
I'm using two WebSecurityConfigurerAdapter classes; one for the API and the other for the UI.
After a successful SAML login the redirect URL now contains the ";jsessionid=6051854D94A0771BB9B99FE573AA4DFD" parameter. Probably because of the stateless policy...?
protected void configure(HttpSecurity http) throws Exception {
List<AbstractAuthenticationProcessingFilter> authFilters = new ArrayList<>();
authFilters.add(new OAuthMacAuthenticationProcessingFilter(authenticationManager(), this.properties));
ApiAuthenticationProcessingFilter apiAuthenticationProcessingFilter = new ApiAuthenticationProcessingFilter(authenticationManager(),authFilters);
http
.csrf()
.disable()
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
.addFilterBefore(apiAuthenticationProcessingFilter, BasicAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
and for the UI part
protected void configure(HttpSecurity http) throws Exception {
http.securityContext().securityContextRepository(customSessionSecurityContextRepository);
http
.httpBasic()
.authenticationEntryPoint(samlEntryPoint());
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class);
var auth = http
.authorizeRequests()
.antMatchers("/saml/**").permitAll()
.antMatchers("/loggedout/**").permitAll()
.antMatchers("/error").permitAll();
auth
.anyRequest()
.authenticated();
http.csrf().disable();
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
http.headers().frameOptions().sameOrigin();
http.exceptionHandling().accessDeniedHandler(this.accessDeniedHandler());
http
.logout()
.disable(); // The logout procedure is already handled by SAML filters.
}
I'll answer this myself. The above code does actually work. The problem was on the remote end, the IDP I was using had some problems that day that resulted in that it didn't work as expected. The day after, it worked.

Spring Security - Custom Authentication Provider and HTTP Basic for Actuator Endpoints

I´ve got a running Spring Boot Application (Spring Boot v2.4.1) and I would like to monitor it using Spring Boot Admin.
I have already setup the server and I can monitor the instance of my application with the /actuator/ endpoint not secured. I have a permitAll() on it.
Now I´d like to secure it, but I do not know how to do it without messing with my current Security Configuration.
I have Spring Security configured to match username and password from a DB and with a CustomAuthenticationProvider. If possible I would like to add a Actuator Endpoints with a HTTP Basic authentication.
This is my current security config:
http.
authorizeRequests()
.antMatchers("/admin/**").hasAuthority(AUTHORITY_ADMIN)
.antMatchers("/user/**").hasAnyAuthority(AUTHORITY_ADMIN, AUTHORITY_USER)
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.successHandler(new CustomUrlAuthenticationSuccessHandler(translator))
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.headers().frameOptions().sameOrigin();
I would like to keep that configuration and also tell spring that whenever a user hits /actuator/ endpoint, it will requiere HTTP Basic Security credentials.
I was thinking on having two #Configuration classes, extending WebSecurityConfigurerAdapter. One would be the one I´ve already got and the other one for the actuator endpoints. But I had no luck with it.
Thank you
Thank you very much
You can create two SecurityFilterChain beans, one for your /actuator/** endpoint with higher priority, and other to every other endpoint with lower priority, like so:
#Bean
#Order(1)
public SecurityFilterChain actuatorWebSecurity(HttpSecurity http) throws Exception {
http.requestMatchers((matchers) -> matchers
.antMatchers("/actuator/**"));
http.authorizeRequests((authz) -> authz
.anyRequest().authenticated());
http.httpBasic();
http.userDetailsService(myUserDetailsService);
...
return http.build();
}
#Bean
#Order(2)
public SecurityFilterChain defaultWebSecurity(HttpSecurity http) throws Exception {
// your current configuration
}
In this configuration, the #Order annotation tells the order that the SecurityFilterChains are gonna be matched against the requests.
This is how I solve it: I create a new #Configuraiton class extending WebSecurityConfigurerAdapter,
I was unable to stop using WebSecurityConfigurerAdapter (as suggested by #Marcus-Hert-da-Coregio in the comments) because if I do not extend it I was not able to define my custom AuthenticationProvider.
This class has #Order(1) so it would take precedence over my other initial configuration (which I set to #Order(2)). And this is it's content:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/actuator/**")
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Then my custom AuthenticationProvider will verify if the given credentials for accessing the actuator endpoints are valid.
Addittional information
The reason why this fails the first time I test it was because I was not setting the initial
.antMatcher("/actuator/**")
by adding it I was telling SpringSecurity that this configuration should only be applied to those endpoints. I get that notion from this article
I hope this helps someone in the future

Spring Security custom authentication provider's authenticate() method is not working

I followed the article Using Custom Authentication Provider Spring Security adding a custom authentication provider in Spring Security.
I found that if I POST to /login, it is redirected to /login.
My custom Authentication Provider's authenticate() is not called.
Even if I use Spring Security's TestingAuthenticationProvider, POST to /login still get redirected to /login.
Is there some thing wrong with my WebSecurityConfigure? This is my configure.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
I use Spring Boot. Do I need to modify the application.properties file? Is there any working sample project on using custom authentication provider?
Have you tried using
http.authorizeRequests()
.antMatchers("/", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
in your WebSecurityConfigure?
You will get a generated login-window that is using your CustomAuthenticationProvider as soon as you are trying to call a page you have not included in
.antMatchers("/", "/webjars/**").permitAll().

Spring Boot Security: How to run authentication filter before CSRF in Spring Boot?

I am always getting unauthorize on Login.
On Login i need to authenticate user as well as generate CSRF token based on JWT token generated from user credentials.
I have CsrfCookieGeneratorFilter but i need to pass JWT generated after sucessfull authentication. My current code always execute CsrfFilterfirst and after that run authentication thing.
So Authentication First and then CsrfCookieGeneraterFilter.
Could anyone guide how to achieve using following builder (I am quite new to this Spring security thing implementation)
Following is code i am trying:
httpSecurity
.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
.csrfTokenRepository(customCsrfTokenRepository)
.and()
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint);
httpSecurity.addFilterAt(new CsrfCookieGeneratorFilter(customCsrfTokenRepository), CsrfFilter.class);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

Spring Boot OAuth2 Single Sign On Concept not working

I am trying to develop OAuth2 Client Application with Single Sign On. I have already developed Authorization Server and tested with Client Credentials flow and its working fine. But when I try to use Authorization Code Grant with Single Sign On I could not get it right. Client application takes me to Login Screen when I access authenticated URL, but once authenticated I am redirected to call back url that's fine. But afterwards I could not access any URL as it all authenticated URL are automatically redirected to CALL BACK url. I have permitted call back url in my Security class
My requirement is once authenticated it will allow other urls normally before authentication it should not allow any url.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeRequests()
.antMatchers("/","/index.html", "/home.html", "/login**","/webjars/**", "/error**","/favicon.ico**","/oauth/token","/oauth/authorize**","/demo/1")
.permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.httpBasic();
Here the call back url is demo/1 and Spring Security is not permitting any other url here.
My requirement is once authenticated it should allow other urls normally before authentication it should not allow any url.
http.authorizeRequests().antMatchers("/","/resources/**", "/**").permitAll().anyRequest().authenticated().and().formLogin()
.loginPage("/").permitAll().usernameParameter("username").passwordParameter("password")
.loginProcessingUrl("/j_spring_security_check").failureUrl("/")
.successHandler(myAuthenticationSuccessHandler()).and().logout().logoutSuccessUrl("/")
.logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("JSESSIONID").and().csrf().disable().headers().frameOptions().sameOrigin();

Resources