I use social login in a spring boot container. This works fine, but when I keep the browser open over night, the next morning I cannot login any more. I need to restart the container and refresh the website, after this it works again.
I hope to get this work by storing the authentication token also in the database by adding JdbcOAuth2AuthorizedClientService. Now, and this is the actual problem, the token is NOT PERSITED although I get these lines in the log:
o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT client_registration_id, principal_name, access_token_type, access_token_value, access_token_issued_at, access_token_expires_at, access_token_scopes, refresh_token_value, refresh_token_issued_at FROM oauth2_authorized_client WHERE client_registration_id = ? AND principal_name = ?]
o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 1, parameter value [google], value class [java.lang.String], SQL type 12
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 2, parameter value [XXXXXX], value class [java.lang.String], SQL type 12
o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO oauth2_authorized_client (client_registration_id, principal_name, access_token_type, access_token_value, access_token_issued_at, access_token_expires_at, access_token_scopes, refresh_token_value, refresh_token_issued_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)]
o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 1, parameter value [google], value class [java.lang.String], SQL type 12
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 2, parameter value [XXXXXX], value class [java.lang.String], SQL type 12
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 3, parameter value [Bearer], value class [java.lang.String], SQL type 12
o.s.jdbc.support.lob.DefaultLobHandler : Set bytes for BLOB with length 165
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 5, parameter value [2022-04-25 09:56:57.137607903], value class [java.sql.Timestamp], SQL type 93
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 6, parameter value [2022-04-25 10:56:56.137607903], value class [java.sql.Timestamp], SQL type 93
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 7, parameter value [https://www.googleapis.com/auth/userinfo.profile,https://www.googleapis.com/auth/userinfo.email,openid], value class [java.lang.String], SQL type 12
o.s.jdbc.support.lob.DefaultLobHandler : Set BLOB to null
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 9, parameter value [null], value class [null], SQL type 93
o.s.jdbc.core.JdbcTemplate : SQL update affected 1 rows
The table keeps empty. I tried with H2 and also PostgreSQL but no difference. The application itself is able to write records to tables using Spring data. No problem at all.
Has anyone an idea? I appriciate for every hint :-)
Thx, SteveP
This is my security configuration:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired final MyAppMemberService memberService;
@Autowired private MyAppProperties properties;
@Resource private ClientRegistrationRepository repo;
@Resource private DataSource dataSource;
@Override
protected void configure(final HttpSecurity http) throws Exception {
final RequestMatcher[] unprotectedGuiApi = new RequestMatcher[] {
new AntPathRequestMatcher("/api/v*/gui/currentUser"),
new AntPathRequestMatcher("/api/v*/gui/oauth2-clients"),
};
final RequestMatcher[] administrationApi = new RequestMatcher[] {
new AntPathRequestMatcher("/api/v*/administration/**")
};
final RequestMatcher[] guiApi = new RequestMatcher[] {
new AntPathRequestMatcher("/api/v*/**"),
new AntPathRequestMatcher("/logout"),
new AntPathRequestMatcher("/**/oauth2/**"),
};
http
.requestMatchers()
.requestMatchers(guiApi)
.and()
.csrf()
.disable()
.cors()
.configurationSource(httpRequest -> properties.getCors())
.and()
.headers()
.contentTypeOptions().disable()
.frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("**/websocket/**").permitAll()
.requestMatchers(unprotectedGuiApi).permitAll()
.requestMatchers(administrationApi).hasRole(Role.ADMIN.name())
.anyRequest().authenticated()
.and()
.logout()
.permitAll()
.logoutSuccessUrl(properties.getGatewayUrl()) // SPA endpoint
.and()
.oauth2Login()
.loginPage(properties.getGatewayUrl() + "/login")
.authorizedClientService(oAuth2AuthorizedClientService())
.userInfoEndpoint()
.userService(oauth2UserService())
.and()
.successHandler(authenticationSuccessHandler());
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
// just registers new users on successful auth
return new MyAppAuthenticationSuccessHandler(properties, memberService);
}
@Bean
public OAuth2UserService oauth2UserService() {
// load member and roles from database
return new MyAppOAuth2UserService(memberService);
}
@Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService() {
return new JdbcOAuth2AuthorizedClientService(new JdbcTemplate(dataSource), repo);
}
}