How to Setup Session Fixation in Spring Boot 3? - java

I am trying to migrate and adapt Baeldung's Spring Security Registration project to use latest Spring Boot 3.0.2. The SecSecurityConfig.java uses sessionFixation().none().
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(PUBLIC_PATHS).permitAll()
.antMatchers("/invalidSession*").anonymous()
.antMatchers("/user/updatePassword*").hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
.anyRequest().hasAuthority("READ_PRIVILEGE")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/homepage.html")
.failureUrl("/login?error=true")
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.authenticationDetailsSource(authenticationDetailsSource)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.and()
.sessionFixation() // <---- This part here
.none() // <---- This part here
.and()
.logout()
.logoutSuccessHandler(myLogoutSuccessHandler)
.invalidateHttpSession(true)
.logoutSuccessUrl("/logout.html?logSucc=true")
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.rememberMe()
.rememberMeServices(rememberMeServices())
.key("theKey");
return http.build();
}
While this format works, I kind of find it difficult to follow the configuration setup, and hence I transformed it to use the overloaded Customizer methods instead. Here is how it turned out to be.
#Bean
public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
return http
.csrf(request -> request.disable())
.authorizeHttpRequests(request ->
request
.requestMatchers(PUBLIC_PATHS).permitAll()
.requestMatchers("/invalidSession*").anonymous()
.requestMatchers("/user/updatePassword*").hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
.anyRequest().hasAuthority("READ_PRIVILEGE")
)
.formLogin(request ->
request
.loginPage("/login")
.defaultSuccessUrl("/homepage.html")
.failureUrl("/login?error=true")
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.authenticationDetailsSource(authenticationDetailsSource)
.permitAll()
)
.sessionManagement(request ->
request
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
)
// sessionFixation.none ??? <---- How this can be configured
.logout(request ->
request
.logoutSuccessHandler(myLogoutSuccessHandler)
.invalidateHttpSession(true)
.logoutSuccessUrl("/logout.html?logSucc=true")
.deleteCookies("JSESSIONID")
.permitAll()
)
.rememberMe(request ->
request
.rememberMeServices(rememberMeServices())
.key("theKey")
)
.build()
;
}
The only part that I am unable to configure is the sessionFixation part with the Customizer setup. Can somebody point me out how to configure it?

As pointed out by #toerktumlare, you can set the sessionFixation in two ways.
.sessionManagement(config ->
config
.sessionFixation().none() // <---- Here
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
)
or add a and() and then configure the sessionFixation()
.sessionManagement(config ->
config
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.and()
.sessionFixation().none() // <---- Here
)

Related

How to configure different paths with Spring Security?

I have struggling to configure security for some different paths I have.
I would like this structure:
/actuator/health <-- open
/api/** <-- hasAnyAuthority
/auth/** <-- basic authentication
all others no access
So far this is what I have
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**") // If you want to override the security provided by Spring Boot.
.addFilter(preAuthFilter())
.cors()
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/api/**").hasAnyAuthority("something")
.antMatchers("/auth/**").authenticated()
.and()
.httpBasic();
}
I would like to add .anyRequest().denyAll() but that doesn't seem to be possible after httpBasic().
Can anyone confirm that the above code will be the same as what I would like?
Example on how to split configuration by path:
#Configuration
public class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/public/**", "/api/register").anonymous() //if you need to allow some path in api
.antMatchers("/api/**", "/api/register/**").hasRole("API_USER")
.and()
.formLogin()
.loginPage("/api/")
.failureHandler(failureHandler())
.loginProcessingUrl("/api/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessUrl("/api/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/api/loginfailed");
}
}
Second path:
#Configuration
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/auth/**")
.authorizeRequests()
.antMatchers("/auth/register").anonymous()
.antMatchers("/auth/**", "/auth/register/**").hasRole("USER")
.and()
.formLogin()
.loginPage("/auth/")
.failureHandler(failureHandler())
.loginProcessingUrl("/auth/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/auth/logout")
.logoutSuccessUrl("/auth/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/auth/loginfailed");
}
}
Now since you have not added security for /actuator/health you can either leave it without one or you can make another adapter for it and permit access to everyone.
Also you should use csrf protection, it is easy to implement.

Spring boot Oauth2 Facebook login - JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

I was working with Spring boot OAuth2 Facebook login, but I encountered the error:
JSON parse error: Cannot deserialize instance of java.lang.String out
of START_OBJECT token
The same code is working for Google and login works as expected. I am following this code on Github(https://github.com/callicoder/spring-boot-react-oauth2-social-login-demo).
Can you please guide me to solve this issue?
Below is the SecurityConfig details
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable()
.formLogin()
.disable()
.httpBasic()
.disable()
.exceptionHandling()
.authenticationEntryPoint(new RestAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers("/","/public/**",
"/login",
"/register",
"/error",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/fonts/*.*",
"/webfonts/*.*",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/auth/**", "/oauth2/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.baseUri("/oauth2/authorize")
.authorizationRequestRepository
(cookieAuthorizationRequestRepository())
.and()
.redirectionEndpoint()
.baseUri("/oauth2/callback/*")
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler);
// Add our custom Token based authentication filter
http.addFilterBefore(tokenAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
Facebook successfully authenticates the login but when it callbacks my application this error appears.
This issue has been fixed in 5.3.0 RELEASE.
You can write custom access token requests and custom message converters. Spring reference has a detailed guide on how to extend the existing functionality.
....
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.formLogin()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.disable()
.exceptionHandling()
.authenticationEntryPoint(new RestAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers("/",
"/error",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/auth/oauth2/**","/login","/signup")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.baseUri("/oauth2/authorize")
.authorizationRequestRepository(cookieAuthorizationRequestRepository())
.and()
.tokenEndpoint()
.accessTokenResponseClient(authorizationCodeTokenResponseClient())
.and()
.redirectionEndpoint()
.baseUri("/oauth2/callback/*")
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(oAuth2AuthenticationFailureHandler);
http.logout()
.logoutSuccessUrl("https://../auth/logout");
// Add our custom Token based authentication filter
http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenResponseClient() {
OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter =
new OAuth2AccessTokenResponseHttpMessageConverter();
tokenResponseHttpMessageConverter.setTokenResponseConverter(new CustomAccessTokenResponseConverter());
RestTemplate restTemplate = new RestTemplate(Arrays.asList(
new FormHttpMessageConverter(), tokenResponseHttpMessageConverter));
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
DefaultAuthorizationCodeTokenResponseClient tokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
tokenResponseClient.setRestOperations(restTemplate);
return tokenResponseClient;
}
I did the tutorial and I also had the same problem the error is in the properties you must delete this and it will work
https://github.com/callicoder/spring-boot-react-oauth2-social-login-demo/blob/master/spring-social/src/main/resources/application.yml
the error is this remove this properties or commit it
spring.security.oauth2.client.provider.facebook.tokenUri= https://graph.facebook.com/v10.0/oauth/access_token

Spring Security refuse all request from client side

I'm using ReactJS with Spring REST and Spring Security and when I do something like:
var myInit = {
method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default'
};
fetch("http://localhost:8080/api/employees", myInit)
.then(function (response) {
console.log(response.json());
}
)
.catch(function (error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
});
Browser respone this: Unexpected token < in JSON at position 0 at <!DOCTYPE...
I'm sure that this problem is the result of my WebSecurityConfig:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/css/**", "/built/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("/", true)
.and()
.httpBasic()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf();
}
Cause when I remove anyRequest.authenticated. It works again but I don't know how to fix.

Keep same URL after login Spring security

i want to stay in the same page after login but spring oblige u to redirect to defaultSuccessUrl
my code is like this
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**","/fonts/**","/js/**","/app/**","/images/**","/partials/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index.html")
.failureUrl("/login?error=true")
.permitAll()
.and().logout().logoutSuccessUrl("/login?logout")
.and().exceptionHandling().accessDeniedPage("/pages/303.html");
}
Set
always-use-default-target="true"
which will force spring-security to go to /index.html
I think you should add an authentication success handler
#Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);//redirect to the previous page
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**","/fonts/**","/js/**","/app/**","/images/**","/partials/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index.html")
.failureUrl("/login?error=true")
.permitAll()
.successHandler(successHandler)//enable success handler
.and().logout().logoutSuccessUrl("/login?logout")
.and().exceptionHandling().accessDeniedPage("/pages/303.html");
}

How remove popup of basic authentication

Does anybody know how to 'hide' popup message from basic authentication without removing possibility to login in the next way: 'http://username:password#example.com/'
Configure your spring like that.
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
.exceptionHandling()
.and()
.rememberMe()
.and()
.formLogin()
.loginProcessingUrl("/user") // rest api
//.usernameParameter("username")
//.passwordParameter("password")
.permitAll()
.and()
.logout()
//.logoutUrl("/api/logout")
//.deleteCookies("JSESSIONID", "CSRF-TOKEN")
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/#/dashboard/home").permitAll()
;
}
In fact, the browser popup logon message if WWW-Authenticate was send by the server. Remove this header from your server that popup will not appear.

Categories

Resources