目录
首先声明,这个报错产生的情况是,在集成完单点登录后,通过生产链接访问系统,在此之前会跳转到一个用于单点登录的界面,类似于这样:
在属于用户名密码后,如果通过了这个okta平台下的验证,会通过url跳转到我们真正的生产系统。
这是正常流程,至于为什么会报SAMLException的错误呢?
正常解决
有2个原因,一个就是正常原因,也就是Idp验证服务器请求我们生产的Sp服务提供者超时,xml配置解决方法如下:
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider"> <constructor-arg> <bean class="java.util.Timer"/> </constructor-arg> <constructor-arg> <bean class="org.opensaml.util.resource.ClasspathResource"> <constructor-arg value="/metadata/idp.xml"/> </bean> </constructor-arg> <property name="parserPool" ref="parserPool"/> <property name="minRefreshDelay" value="120000"/> <property name="maxRefreshDelay" value="300000"/> </bean>
其原理就是把配置在IOC容器中的ResourceBackedMetadataProvider的超时属性:minRefreshDelay、maxRefreshDelay重新设置下。
太老了,现在注解版本一般这么用:
@Bean
public ExtendedMetadataDelegate idpMetadataLoader() {
if (StringUtils.isBlank(samlProperties.getIdpXml()) || !samlProperties.getIdpXml().endsWith(".xml")) {
throw new IllegalArgumentException("demo.saml.idp-xml must not be null or empty and must be a xml file.");
}
try {
final File file = ResourceUtils.getFile(samlProperties.getIdpXml());
Resource idpResource = new FilesystemResource(file.getPath());
Timer refreshTimer = new Timer(true);
ResourceBackedMetadataProvider delegate;
delegate = new ResourceBackedMetadataProvider(refreshTimer, idpResource);
delegate.setMinRefreshDelay(120000);
delegate.setMaxRefreshDelay(300000);
delegate.setParserPool(parserPool());
ExtendedMetadata extendedMetadata = extendedMetadata().clone();
ExtendedMetadataDelegate provider = new ExtendedMetadataDelegate(delegate, extendedMetadata);
provider.setMetadataTrustCheck(true);
provider.setMetadataRequireSignature(false);
String idpName = file.getName().replaceAll(".xml", "");
extendedMetadata.setAlias(idpName);
// 配置 IDP 元数据的 provider
LOGGER.info("Loaded Idp Metadata bean {}: {}", idpName, file.getPath());
return provider;
} catch (Exception e) {
throw new IllegalStateException("Unable to initialize IDP Metadata", e);
}
}
笔者遇到情况
笔者遇到的情况,稍微特殊点,其实正常来说一般也不会出现超时错误,笔者的情况是,测试和生产服务器都配置在了例如okta的生产环境下。
这样就会造成一个问题,他们都可以过单点登录界面,但是笔者这边用户遇到的情况是一输入生产地址,就算通过了单点登录验证,后面会直接报401错误,后台报错就和标题显示一样SAMLException。
原因
其实这个主要和笔者的配置有关系,主要就是测试和生产服务器都配置在了一个okta环境下,如果先登录了测试地址,是没问题,可以正常访问,但是登录了测试再登录生产,就会出现如题报错。
解决办法
清空浏览器缓存,直接输入生产地址,访问即可。
小结
究其原因,主要还是测试和生产服务器都配置在了一套环境,然后这个环境中其实可以设置不同的Application,这样的话,测试与生产变会产生同又不同的变化,同的是单点登录他们都可以进去。
不同的是,进去后不同的环境与okta的Idp服务器交互产生的token其实是不一样的,你用测试的token去进生产,不就报401错了嘛。