该体系结构是一个具有多个rps的身份验证服务器(op)。请检查下面的图片。
我能够成功地用rp启动的注销注销,也就是说,如果我从任何客户端注销,客户端(rp)就会注销,op也会注销。
请查找openid提供者发现元数据;
{
"jwks_uri":"https://<Auth Server URL>/token_keys",
"subject_types_supported":["public"],
"end_session_endpoint":"https://<Auth Server URL>/logout",
"issuer":"https://<Auth Server URL>/oauth/token",
"authorization_endpoint":"https://<Auth Server URL>/oauth/authorize",
"token_endpoint":"https://<Auth Server URL>/oauth/token"
}
与 "end_session_endpoint"
在发现中,我可以在客户端使用以下代码执行rp启动的注销操作,
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.nimbusds.jose.shaded.json.JSONArray;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ClientRegistrationRepository clientRegistrationRepository;
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/assets/**").antMatchers("/assets/bundles/**");
}
@Bean(name = "oidcUserService")
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
return new CustomOidcUserService();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().headers(headers -> headers.cacheControl().and()
.addHeaderWriter(new StaticHeadersWriter("X-UA-Compatible", "IE=edge"))
.frameOptions(frameOptions -> frameOptions.sameOrigin()).httpStrictTransportSecurity())
.authorizeRequests(authorize -> authorize
.antMatchers("/error").permitAll()
.anyRequest().authenticated())
.oauth2Login(oauthLogin -> oauthLogin
.userInfoEndpoint()
.oidcUserService(this.oidcUserService()))
.logout(logout -> logout
.logoutSuccessHandler(oidcLogoutSuccessHandler())
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID","CSRF-TOKEN","XSRF-TOKEN")
.permitAll())
.csrf((csrf) -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()));
}
private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() {
OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler = new OidcClientInitiatedLogoutSuccessHandler(this.clientRegistrationRepository);
oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
return oidcLogoutSuccessHandler;
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
但是我不知道如何实现op-initiatedlogot,如果op会话过期或op注销,它将注销op下的所有客户端。有什么例子吗?我已经为此研究了几天,并发现有另一个关键叫 "check_session_iframe"
但在spring中找不到合适的文档。如果你有任何例子,请分享。谢谢您。
2条答案
按热度按时间goucqfw61#
如果op的元数据不包含
check_session_iframe
frontchannel_logout_supported
或者backchannel_logout_supported
,则它根本不支持单次注销,这将在客户端触发注销,即“op initiated logout”。xpszyzbs2#
这个
check_session_iframe
包含由op控制的url。客户端将把这个url嵌入为iframe,也称为op iframe。opiframe可以访问openid提供者的用户代理状态(因为它是同一个域)。客户端将创建另一个iframe,rp iframe,向op iframe发送postmessage请求,以检查会话状态。op-iframe随后将向rp-iframe响应postmessage请求,并返回结果(更改、未更改或错误)。关于会话管理规范的客户机部分,惟一需要做的就是嵌入op iframe,给它一个id,这样就可以向它发送postmessage请求,并在rp iframe中处理来自它的postmessage请求。查看规范中的伪代码:https://openid.net/specs/openid-connect-session-1_0.html#rpiframe