How to enable saml2 on specific endpoint and use jwt authentication on others? - spring

i have to authentificate the user with saml2 on specific endpoint when saml2 success i create jwt token who permite to access to other endpoints.
My security config look like this
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
authenticationProvider.setResponseAuthenticationConverter(groupsConverter());
http
.cors()
.and()
.csrf()
.disable()
.addFilterBefore(new JWTFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class)
.saml2Login(saml2 -> {
saml2
.authenticationManager(new ProviderManager(authenticationProvider));
}
)
.saml2Logout(withDefaults());
return http.build();
}
But my problem is that when the user is not logged on other endpoints saml2 login form is displayed it should throw http 403 response
how to enable authenticate saml2 on specific endpoint and enable jwt token on other endpoints?
how to implement saml2 and jwt together on spring security 6 spring boot?
or how to disable saml2login on specific endpoint?

Related

How do i allow access certain request path to every user so that he/she can register user in spring security 6?

In spring security 5.7.5, I had the following security filter chain that allows unauthenticated users to easily register accounts.
Code in spring Security 5.7.5
#Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests(
authorize ->
authorize
.mvcMatchers("/user/**").permitAll()
.mvcMatchers("/**").authenticated()
).formLogin(Customizer.withDefaults());
return http.build();
But now, The previous way code is not working. How should I configure a filter chain that allows anyone to register accounts?
Present Code
#EnableWebSecurity
public class SecurityConfig {
#Bean
#Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults());
//when unauthenticated user tries to login the resource server
// redirect him/her to login page
http
.exceptionHandling(
exception ->
exception.authenticationEntryPoint(
new LoginUrlAuthenticationEntryPoint("/login")
)
);
return http.build();
}
#Bean
#Order(2)
public SecurityFilterChain appSecurityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.disable()
.authorizeHttpRequests(
authorize ->
authorize
.requestMatchers("/user/registerUser",
"/user/getAllUser").permitAll()
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.build();
}
}
I'm getting 401 unauthorized in postman when i request for /user/registerUser and /user/getAllUser url. What i'm trying is, registering user account by unauthenticated users. I belive my security filter chain is sending me to /login page to authenticate which i don't want for register url.

How to get CSRF token using Postman?

I'm using Spring Security to generate the CSRF token for me.
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
...etc
}
But I'm unable to find the cookies in Postman, no cookie found for X-XSRF-TOKEN to use.
Thanks to #SteveRiesenberg.
in Spring Security 6 , CSRF tokens are defered

Spring Security 6 configuration with multiple security configs

I'm trying to setup my Spring Boot 3.0 / Spring Security 6 app with multiple security configs.
only /oauth/token should use/allow/enforce basic auth
all other endpoints will use/allow/enforce bearer auth
The issue I'm running into is that if I send a GET request to /test with the header Authorization: Basic xxx the basic auth filter is still picking it up.
This is what I have so far. The bearer filter isn't implemented yet, but for the sake of this question, let's assume all other endpoints should be wide open instead. How can I get them to bypass the basic auth filter if a user passes in basic auth header?
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
return http.build();
}
Like this one:
private static final String[] RESOURCE_ARGS = new String[]{
"/test/**"
};
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers(RESOURCE_ARGS).permitAll();
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
....
}

Spring Security with OAuth2 losing session

We have a Spring Boot-based Gateway using Spring Security, OAuth2 login, and Zuul routing. It is also using Spring Session to store sessions in Redis. This Gateway stores an OAuth2 token in the session and forwards the OAuth2 Bearer token to backend services.
We have an issue where users are being signed out quite often. It appears this happens roughly hourly. We are not even quite sure what is causing this with all the different tools in place.
Our session cookie in the browser expires in a longer period of time. So I suspect it is either Spring invalidating the session, or the OAuth2 token expiring.
From a quick inspection of the code, it appears that OAuth2TokenRelayFilter supports refreshing the token. Is this correct?
How can track down the cause of this and fix it?
For reference, we are using these versions:
Spring Boot 2.1.12
Spring Cloud Greenwich.SR4
Here are some relevant snippets.
Our web security config for the web pages.
#Configuration
#EnableWebSecurity
#EnableOAuth2Sso
#Order(SecurityProperties.BASIC_AUTH_ORDER - 2)
#Profile("!security-disabled")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/login", "/login/**", "/favicon.ico").permitAll()
.antMatchers("/signout").authenticated()
.anyRequest().hasAnyRole("ADMIN", "MEMBER")
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.httpBasic()
.disable()
.formLogin()
.disable()
.logout()
.logoutUrl("/signout")
.deleteCookies("SESSION")
.and()
// #formatter:on
}
Security configuration for API paths.
#Configuration
#Order(SecurityProperties.BASIC_AUTH_ORDER - 2 - 10)
#Profile("!security-disabled")
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter
{
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers("/**").hasAnyRole("ADMIN", "MEMBER")
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.headers()
.frameOptions().sameOrigin()
.and()
.httpBasic()
.disable()
.formLogin()
.disable()
.logout()
.disable()
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
// #formatter:on
}
}
Update
We have done some debugging of the Spring internals. First, we found that we were missing an OAuth2RestTemplate. Per the OAuth2 Boot documentation we found how to add it with:
#Bean
public OAuth2RestTemplate oauth2RestTemplate(
OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details)
{
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
This is now throwing an exception when OAuth2TokenRelayFilter calls restTemplate.getAccessToken().getValue();.
A redirect is required to get the users approval
This exception is thrown from AuthorizationCodeAccessTokenProvider.
OAuth2TokenRelayFilter
OAuth2TokenRelayFilter is a pre type filter which set the contexts with ACCESS_TOKEN and TOKEN_TYPE which will be used for the further authentication. It validates the tokens using getAccessToken() method and responds with "Cannot obtain valid access token" with 401 status.
You may check the validity of tokens and refresh token is correctly configured with grant_type as refresh_token as The Refresh Token grant type is used by clients to exchange a refresh token for an access token when the access token has expired which allows clients to continue to have a valid access token without further interaction with the user.
In case if you want to disable OAuth2TokenRelayFilter, you may use the following
zuul.OAuth2TokenRelayFilter.pre.disable=true

Spring Security with filters permitAll not working

I've got this security config:
#Override
public void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(
new JwtLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(
new JwtAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
http.csrf().disable()
.authorizeRequests().antMatchers("/", "/register").permitAll()
.and()
.authorizeRequests().anyRequest().authenticated();
}
The two filters are doing authentication work: loginFilter checks credentials in the post body and then add cookie to the response. The authenticationFilter checks the auth cookie.
However, permitAll does not let the root route and "/register" route pass (aka. still going through the authenticationFilter, which I thought permitAll would let these routes pass the filters)
What's wrong?
permitAll() does not ignore filters. It simply grants access regardless of whether or not an Authentication is present in a request's security context after all filters have been processed.
You should check your filters and any AuthenticationProvider implementations that they use to to ensure that they are not breaking the execution flow of Spring Security by throwing unchecked/uncaught exceptions or expressly sending a response on a failed authentication.

Resources