[英]Spring Boot oauth2 social login: Cannot login after session timeout
我在 spring 引導容器中使用社交登錄。 這很好用,但是當我在晚上保持瀏覽器打開時,第二天早上我就無法再登錄了。 我需要重新啟動容器並刷新網站,之后它再次工作。
我希望通過添加JdbcOAuth2AuthorizedClientService
將身份驗證令牌也存儲在數據庫中來完成這項工作。 現在,這是實際的問題,盡管我在日志中得到了這些行,但令牌沒有被保留:
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
桌子一直空着。 我嘗試使用 H2 和 PostgreSQL 但沒有區別。 應用程序本身能夠使用 Spring 數據將記錄寫入表。 完全沒有問題。
有人有想法嗎? 我喜歡每一個提示:-)
謝謝,史蒂夫
這是我的安全配置:
@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);
}
}
這篇文章讓我想到它可能不會提交到 DB: 當在 spring-data-jpa 和 spring-security-oauth 的 JdbcTokenStore 之間共享 Jdbc 連接池時,如何處理事務?
使用這種日志記錄技術,我可以看到 INSERT 語句已發送到 DB https://vladmihalcea.com/the-best-way-to-log-jdbc-statements/但沒有最終日志語句
o.s.jdbc.core.JdbcTemplate : SQL update affected 1 rows
我采用了這樣的 WebSecurityConfiguration:
@Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService() {
return new TransactionalJdbcOAuth2AuthorizedClientService(jdbcTemplate, repo);
}
並補充說:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class TransactionalJdbcOAuth2AuthorizedClientService extends JdbcOAuth2AuthorizedClientService {
public TransactionalJdbcOAuth2AuthorizedClientService(final JdbcOperations jdbcOperations, final ClientRegistrationRepository clientRegistrationRepository) {
super(jdbcOperations, clientRegistrationRepository);
}
@Override
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(final String clientRegistrationId, final String principalName) {
return super.loadAuthorizedClient(clientRegistrationId, principalName);
}
@Override
public void saveAuthorizedClient(final OAuth2AuthorizedClient authorizedClient, final Authentication principal) {
super.saveAuthorizedClient(authorizedClient, principal);
}
@Override
public void removeAuthorizedClient( final String clientRegistrationId, final String principalName) {
super.removeAuthorizedClient(clientRegistrationId, principalName);
}
}
現在它堅持了:我問自己? 我是第一個使用 Spring 的 JdbcOAuth2AuthorizedClientService 的人嗎? 無論如何,JavaDoc 或任何 Spring 文檔中都沒有提示。 希望這個提示對其他人有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.