我需要在EAR应用程序中创建的各种WAR中执行SSO。我按照这里提供的演示https://github.com/pac4j/buji-pac4j-demo并在EAR中的每个WAR中配置了每个shiro.ini,其方式与演示中提供的完全相同。我正在使用资源:samlKeystore.jks(具有相同的凭据)并尝试使用相同的okta(resource:metadata-okta.xml)IDP进行连接。但是,当我点击“受SAML保护的URL:saml / index.jsp”链接时,出现此错误:
2016-04-29 16:20:11,460 ERROR [io.undertow.request](默认任务-13)UT005023:对/MyWebA/saml/index.jsp的异常处理请求:javax.servlet.ServletException:org。 pac4j.saml.exceptions.SAMLException:Keystore没有私钥 在org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196) 在org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148)
...
引起:org.pac4j.saml.exceptions.SAMLException:Keystore没有私钥 在org.pac4j.saml.crypto.KeyStoreCredentialProvider.getPrivateKeyAlias(KeyStoreCredentialProvider.java:175) 在org.pac4j.saml.crypto.KeyStoreCredentialProvider。(KeyStoreCredentialProvider.java:98) 在org.pac4j.saml.crypto.KeyStoreCredentialProvider。(KeyStoreCredentialProvider.java:105)
这很奇怪,因为我在resources文件夹中实际有samlKeystore.jks。
我的问题是:
1)为什么即使我使用演示附带的同一个密钥库,我也会收到“Keystore没有私钥”的问题?顺便说一句,按原样运行演示没有这个问题。
2)我是否想自己配置IDP,我需要一个描述我的EAR应用程序的SP元数据。我注意到shiro.ini将此配置设置为:saml2Config.serviceProviderMetadataPath = resource:sp-metadata.xml。但我可以找到sp-metadata.xml(如果它意味着生成一个)。如何使用shiro.ini生成sp-metadata.xml?由于我使用的是buji-pac4j和pac4j-saml,我无法弄清楚如何使用此处描述的2个选项https://github.com/pac4j/pac4j/wiki/Clients#saml-support
编辑包含pom.xml和shiro.ini
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>MyEARProject</groupId>
<artifactId>MyEARProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>MyEAR</groupId>
<artifactId>MyEAR</artifactId>
<packaging>ear</packaging>
<properties>
<mywebversion>0.0.2</mywebversion>
<pac4jVersion>1.8.8</pac4jVersion>
<bujiVersion>1.4.2</bujiVersion>
<javaVersion>1.8</javaVersion>
</properties>
<dependencies>
<dependency>
<groupId>io.buji</groupId>
<artifactId>buji-pac4j-servlet</artifactId>
<version>${bujiVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oauth</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-openid</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-cas</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-http</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-saml</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oidc</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-gae</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-ldap</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-sql</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-mongo</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-stormpath</artifactId>
<version>${pac4jVersion}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.4</version>
<scope>provided</scope>
</dependency
<dependency>
<groupId>com.my</groupId>
<artifactId>webApp1</artifactId>
<version>${mywebversion}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.my</groupId>
<artifactId>webAppRest</artifactId>
<version>${mywebversion}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.my</groupId>
<artifactId>webApp2</artifactId>
<version>${mywebversion}</version>
<type>war</type>
</dependency>
</dependencies>
</project>
这是我的shiro.ini配置
[main]
############################################################################
# PROVIDERS :
############################################################################
#sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
#sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
#sessionManager.sessionDAO = $sessionDAO
#cookie = org.apache.shiro.web.servlet.SimpleCookie
#cookie.name = SSOcookie
#cookie.path = /
#cookie.domain = localhost
#sessionManager.sessionIdCookie = $cookie
#securityManager.sessionManager = $sessionManager
#cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
#cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
#securityManager.cacheManager = $cacheManager
#securityManager.sessionMode = native
#Para testing:
#ssl.enabled=false
subjectFactory = io.buji.pac4j.ClientSubjectFactory
securityManager.subjectFactory = $subjectFactory
facebookClient = org.pac4j.oauth.client.FacebookClient
facebookClient.key = 145278422258960
facebookClient.secret = be21409ba8f39b5dae2a7de525484da8
twitterClient = org.pac4j.oauth.client.TwitterClient
twitterClient.key = CoxUiYwQOSFDReZYdjigBA
twitterClient.secret = 2kAzunH5Btc4gRSaMr7D7MkyoJ5u1VzbOOzE8rBofs
simpleAuthenticator = org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator
formClient = org.pac4j.http.client.indirect.FormClient
formClient.loginUrl = http://localhost:8080/webApp1/loginForm.jsp
formClient.authenticator = $simpleAuthenticator
basicAuthClient = org.pac4j.http.client.indirect.IndirectBasicAuthClient
basicAuthClient.authenticator = $simpleAuthenticator
casClient = org.pac4j.cas.client.CasClient
casClient.casLoginUrl = https://casserverpac4j.herokuapp.com
#casClient.gateway=true
vkClient = org.pac4j.oauth.client.VkClient
vkClient.key = 4224582
vkClient.secret = nDc4IHTqu8ioFMkHKifq
saml2Config = org.pac4j.saml.client.SAML2ClientConfiguration
saml2Config.keystorePath = resource:samlKeystore.jks
saml2Config.keystorePassword = pac4j-demo-passwd
saml2Config.privateKeyPassword = pac4j-demo-passwd
saml2Config.identityProviderMetadataPath = resource:metadata-okta.xml
saml2Config.maximumAuthenticationLifetime = 3600
saml2Config.serviceProviderEntityId = http://localhost:8080/webApp1/callback?client_name=SAML2Client
saml2Config.serviceProviderMetadataPath = resource:sp-metadata.xml
saml2Client = org.pac4j.saml.client.SAML2Client
saml2Client.configuration = $saml2Config
clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8080/webApp1/callback
clients.clients = $facebookClient,$twitterClient,$formClient,$basicAuthClient,$casClient,$vkClient,$saml2Client
############################################################################
# REALM & FILTERS :
############################################################################
clientsRealm = io.buji.pac4j.ClientRealm
clientsRealm.defaultRoles = ROLE_USER
clientsRealm.clients = $clients
clientsFilter = io.buji.pac4j.ClientFilter
clientsFilter.clients = $clients
clientsFilter.failureUrl = /error500.jsp
facebookRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
facebookRoles.client = $facebookClient
twitterRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
twitterRoles.client = $twitterClient
formRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
formRoles.client = $formClient
basicAuthRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
basicAuthRoles.client = $basicAuthClient
casRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
casRoles.client = $casClient
vkRoles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
vkRoles.client = $vkClient
saml2Roles = io.buji.pac4j.filter.ClientRolesAuthorizationFilter
saml2Roles.client = $saml2Client
[urls]
/facebook/** = facebookRoles[ROLE_USER]
/twitter/** = twitterRoles[ROLE_USER]
/form/** = formRoles[ROLE_USER]
/basicauth/** = basicAuthRoles[ROLE_USER]
/cas/** = casRoles[ROLE_USER]
/vk/** = vkRoles[ROLE_USER]
/saml/** = saml2Roles[ROLE_USER]
/callback = clientsFilter
/logout = logout
/** = anon
由于我想在我的EAR中的各种WAR中执行SSO,我最初添加了EhCacheManager,但后来我收到了以下错误。
2016-05-01 22:03:38,126 INFO [org.apache.shiro.web.env.EnvironmentLoader] (ServerService Thread Pool -- 163) Starting Shiro environment initialization.
2016-05-01 22:03:38,179 ERROR [org.apache.shiro.web.env.EnvironmentLoader] (ServerService Thread Pool -- 163) Shiro environment initialization failed: org.apache.shiro.config.ConfigurationException: Unable to instantiate class [org.apache.shiro.cache.ehcache.EhCacheManager] for object named 'cacheManager'. Please ensure you've specified the fully qualified class name correctly.
at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:151)
at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:119)
at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:161)
at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:124)
at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:102)
at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:88)
at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:46)
at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123)
at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47)
at org.apache.shiro.web.env.IniWebEnvironment.createWebSecurityManager(IniWebEnvironment.java:203)
at org.apache.shiro.web.env.IniWebEnvironment.configure(IniWebEnvironment.java:99)
at org.apache.shiro.web.env.IniWebEnvironment.init(IniWebEnvironment.java:92)
at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45)
at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40)
at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:221)
at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:133)
at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58)
at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187)
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:198)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [org.apache.shiro.cache.ehcache.EhCacheManager] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found.
at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:148)
at org.apache.shiro.util.ClassUtils.newInstance(ClassUtils.java:164)
at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:144)
... 26 more
Buji-pac4j是否使用带有WAR的SSO的EhCache配置?
答案 0 :(得分:0)
1)我从未遇到过这个错误,看起来很奇怪。你能尝试使用最新的pac4j-saml版本,我的意思是1.8.8,其中私钥选择算法有所改进吗?
2)SP元数据是根据您定义的SAML2Configuration生成的,并且基于serviceProviderMetadataPath属性定位。更改SAML2Configuration以生成适当的配置
答案 1 :(得分:0)
对于(2),我发现在处理sAML请求时,在shiro.ini的[main]部分中设置以下条目将在Web项目的根文件夹中生成文件“ sp-metadata.xml”。 :
saml2Config.serviceProviderMetadataPath = sp-metadata.xml
saml2Config.forceServiceProviderMetadataGeneration = true
对于(1),听起来好像没有密钥库放置在类路径中。我发现了一个侧面说明:我的项目对待资源文件夹与src文件夹的不同之处在于它过滤了资源。这破坏了密钥库,直到我将密钥库移到src文件夹。