技术标签: python java linux 大数据 eclipse
sso 服务端配置
编者注:本教程于2017年3月20日更新。所做的更新是为了更正2b步骤4中的代码。 将安全配置应用于IdentityServer配置文件。
您想要在混合云环境中将云服务公开为JavaEnterprise Edition(Java EE)应用程序。 但是,如何通过使用专用网络中的现有安全基础结构来确保这些应用程序的安全性?
本系列的第1部分着重于身份提供商(IdP)和服务提供商(SP)之间的标准身份验证机制。 它基于使用安全性声明标记语言(SAML)2.0对用户身份信息的声明 。 它还说明了Web服务调用之间的身份传播。 在继续本部分之前,您必须熟悉SAML概念和Eclipse上的Java EE开发。
安全声明标记语言(SAML)是必须根据OASIS标准规范(也称为SAML令牌)编写的XML文档。 根据标准的Java身份验证和授权服务(JAAS)规范,SAML令牌包含应用程序用来对用户进行身份验证和执行基于角色的授权的信息。 通过使用SAML令牌,应用程序不必提示用户提供其凭据。 在应用程序体系结构中, 身份提供者(IdP)充当生成SAML令牌的角色。
以下代码段是SAML令牌的示例。
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
InResponseTo="_UQ1kDQbfg5KPBBxlMJOEd8jkUOQ1hBLo"
IssueInstant="2017-02-17T08:52:44.650Z"
Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
samlsso.sample.net
</saml2:Issuer>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
ID="Assertion1487321564650" IssueInstant="2017-02-17T08:52:44.650Z"
Version="2.0">
<saml2:Issuer>samlsso.sample.net</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#Assertion1487321564650">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>nKYxEAMG1LY4H+LqR22KJ/vqyb8=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
m5V44OFKU1PMdibileobvVVA8NVZMKRmKAauOin2f+Kr1WQ [...] Z/5JcU/qw==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIDRzCCAi+gAwIBAgIEKa/crTANBgkqhkiG9w0BAQsFADBUMRMwEQYKCZImiZPyLGQBGRYDbmV0
MRYwFAYKCZImiZPyLGQBGRYGc2FtcGxlMRcwFQYKCZImiZPyLGQBGRYHc2FtbHNzbzEMMAoGA1UE
AxMDaWRwMB4XDTE2MTExNzE0MjkwM1oXDTMwMDcyNzE0MjkwM1owVDETMBEGCgmSJomT8ixkARkW
A25ldDEWMBQGCgmSJomT8ixkARkWBnNhbXBsZTEXMBUGCgmSJomT8ixkARkWB3NhbWxzc28xDDAK
BgNVBAMTA2lkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ9Ai1Cs4c7CIwpJ/N0X
ub83SyYZz509A5/y65sj2iBFaIRCgzm0s+F6jCsyxpRd8fVgOtJ56CNdJkN+Zw7pOGvrD/EIvjn8
8SwCx0GDdxgtP4lfbQ7DhakSLw2hCui7yB9ijbIJjd+1f2IJbIv8TqYH4RG3kQue6i9e47W8Z4jY
URivaX/omXJvoBBBRO6a23n+jrQ7hk9KCACKfCEmlMaO9meg+mXRXyAXLnyaGw7W7qk27/7QB5uH
s2WhXIxy+wt3PrTZ9q2x413/chbQvRfrgxfhUA/GGFiWTa7x+sZ2g6bKLcGPqkjuJRuhNkeWkuOj
thnygoBz58A4f8MBqTUCAwEAAaMhMB8wHQYDVR0OBBYEFO8nqGs+aMkoBg/Ll4rbLZD9+V1mMA0G
CSqGSIb3DQEBCwUAA4IBAQAdL6/tA2faup5/BOmuBIA9CDCNk9uUf56ikFCMtP93ARsgKWPRLgba
i6tYC5qaVDOBn3Kcr0Wy3egObQsQE6lP4J7SCQUn/miBP/hogrc2uDhOuvCrBHvwGxRbhsMPUUCC
73pxGSKFf4tVKbsm8Y1k3840fJwvfc4NKn5JCj0ShEoRMmf/UkcEOTWbOEQrErrCtA3Czxo5JtKh
t8s1RPPg9p6lC5qk9Ob6tnLGh4mtHE9dc4FifMOaccCMTwc5O34jP7AM+avRcyvSw5b0jDhER8re
ubErEwK3ceaoAejlPJQbmMt9SOJfXDS7P1jc4yuWEAolJeA7CsX9xkTb3Rj3
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2:Subject>
<saml2:NameID>alice</saml2:NameID>
<saml2:SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData
InResponseTo="_UQ1kDQbfg5KPBBxlMJOEd8jkUOQ1hBLo"
NotOnOrAfter="2017-02-17T09:52:44.650Z"
Recipient="https://localhost:9443/ibm/saml20/sp/acs" />
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2017-02-17T08:22:44.650Z"
NotOnOrAfter="2017-02-17T09:22:44.650Z">
<saml2:AudienceRestriction>
<saml2:Audience>https://localhost:9443/ibm/saml20/sp
</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AttributeStatement>
<saml2:Attribute Name="Membership">
<saml2:AttributeValue>
CN=CloudServiceUsers,dc=samlsso,dc=sample,dc=net
</saml2:AttributeValue>
<saml2:AttributeValue>
CN=LocalServiceUsers,dc=samlsso,dc=sample,dc=net
</saml2:AttributeValue>
<saml2:AttributeValue>
CN=IdentityRequestors,dc=samlsso,dc=sample,dc=net
</saml2:AttributeValue>
<saml2:AttributeValue>
CN=FrontendServiceUsers,dc=samlsso,dc=sample,dc=net
</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
<saml2:AuthnStatement AuthnInstant="2017-02-17T08:52:44.650Z">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>
在这个XML示例中,最有趣的部分是Assertion部分。 它包含令牌发行者,文档签名,主题,条件和属性声明。
当SAML接收者信任令牌时,将对用户进行身份验证。 接收方应用程序使用从SAML令牌中提取的用户名和组以编程方式为用户创建安全上下文。 在安全上下文可用之后,接收方应用程序可以启动授权API(JAAS),以验证用户是否具有访问受保护资源(例如Servlet和EJB)所需的权限。
您可以看到可以通过使用SAML断言用户身份而无需知道用户的凭据。 这种方法使SAML成为在网络中不同域上实现SSO的可能解决方案。 那么,SAML接收者如何信任SAML令牌?
用于建立信任的模型称为非对称密码术 。 此模型基于同时生成并通过数学公式链接在一起的一对密钥(私钥和相应的公钥)。 私钥用于加密,而相应的公钥用于解密。 非对称密码模型背后的主要概念是,只有使用相应的公钥才能解密使用私钥加密的数据。
在我们的方案中,身份提供者是私钥的所有者,并且不得与任何人共享。
需要信任身份提供者的SAML接收器配置为在配置文件或信任库中保存身份提供者的公钥。 当身份提供者发出SAML令牌时,身份提供者将通过两步过程生成签名值。 首先,它将哈希算法应用于Assertion元素的内容。 其次,它使用私钥对哈希进行加密。 然后,身份提供者将签名值添加到SAML令牌的SignatureValue元素,并将该令牌发送给请求者。
SAML接收器应用程序读取SAML令牌并执行两个操作:
如果哈希值相等,则接收方可以信任SAML令牌。 而且,它确保签名的内容不被篡改。
有关SAML身份验证如何工作的更多信息,请参阅WebSphere Application Server安全域中的SAML断言 。
当您为传统的Web应用程序实现SSO时,首先,请考虑根据OASIS规范共同努力使SSO成为可能的参与者:
下图显示了我们的示例应用程序,其中SP发起的SSO actor位于左侧的较大框中。 SP是WebSphere Liberty中的功能。 IdP是一个Web应用程序,我们将其安装在名为IdentityServer的Liberty实例上。
尽管免费的IdP实施在网络上,但是它们缺少示例配置。 我们从头开始实现,并将其作为Liberty功能提供,以使配置尽可能简单。 我们还引用了可用于Liberty的Open SAML库,这样我们就不必下载更多的开源库来生成断言。 此方案不是完全兼容的IdP实施。 如果你需要移动到生产,你可能想采取一个产品 ,它提供了IDP实施和支持。
IdP元数据是一个描述IdP的XML文件,其中包含以下信息:
以下示例显示了我们方案的IdP元数据。
<?xml version="1.0"?>
<md:EntityDescriptor id="samlsso.sample.net"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
validUntil="2022-10-29T22:57:55Z"
cacheDuration="PT1478213875S" entityID="samlsso.sample.net">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
MIIDRzCCAi+gAwIBAgIEKa/crTANBgkqhkiG9w0BAQsFADBUMRMwEQYKCZImiZPyLGQBGRYDbmV0
MRYwFAYKCZImiZPyLGQBGRYGc2FtcGxlMRcwFQYKCZImiZPyLGQBGRYHc2FtbHNzbzEMMAoGA1UE
AxMDaWRwMB4XDTE2MTExNzE0MjkwM1oXDTMwMDcyNzE0MjkwM1owVDETMBEGCgmSJomT8ixkARkW
A25ldDEWMBQGCgmSJomT8ixkARkWBnNhbXBsZTEXMBUGCgmSJomT8ixkARkWB3NhbWxzc28xDDAK
BgNVBAMTA2lkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ9Ai1Cs4c7CIwpJ/N0X
ub83SyYZz509A5/y65sj2iBFaIRCgzm0s+F6jCsyxpRd8fVgOtJ56CNdJkN+Zw7pOGvrD/EIvjn8
8SwCx0GDdxgtP4lfbQ7DhakSLw2hCui7yB9ijbIJjd+1f2IJbIv8TqYH4RG3kQue6i9e47W8Z4jY
URivaX/omXJvoBBBRO6a23n+jrQ7hk9KCACKfCEmlMaO9meg+mXRXyAXLnyaGw7W7qk27/7QB5uH
s2WhXIxy+wt3PrTZ9q2x413/chbQvRfrgxfhUA/GGFiWTa7x+sZ2g6bKLcGPqkjuJRuhNkeWkuOj
thnygoBz58A4f8MBqTUCAwEAAaMhMB8wHQYDVR0OBBYEFO8nqGs+aMkoBg/Ll4rbLZD9+V1mMA0G
CSqGSIb3DQEBCwUAA4IBAQAdL6/tA2faup5/BOmuBIA9CDCNk9uUf56ikFCMtP93ARsgKWPRLgba
i6tYC5qaVDOBn3Kcr0Wy3egObQsQE6lP4J7SCQUn/miBP/hogrc2uDhOuvCrBHvwGxRbhsMPUUCC
73pxGSKFf4tVKbsm8Y1k3840fJwvfc4NKn5JCj0ShEoRMmf/UkcEOTWbOEQrErrCtA3Czxo5JtKh
t8s1RPPg9p6lC5qk9Ob6tnLGh4mtHE9dc4FifMOaccCMTwc5O34jP7AM+avRcyvSw5b0jDhER8re
ubErEwK3ceaoAejlPJQbmMt9SOJfXDS7P1jc4yuWEAolJeA7CsX9xkTb3Rj3
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
MIIDRzCCAi+gAwIBAgIEKa/crTANBgkqhkiG9w0BAQsFADBUMRMwEQYKCZImiZPyLGQBGRYDbmV0
MRYwFAYKCZImiZPyLGQBGRYGc2FtcGxlMRcwFQYKCZImiZPyLGQBGRYHc2FtbHNzbzEMMAoGA1UE
AxMDaWRwMB4XDTE2MTExNzE0MjkwM1oXDTMwMDcyNzE0MjkwM1owVDETMBEGCgmSJomT8ixkARkW
A25ldDEWMBQGCgmSJomT8ixkARkWBnNhbXBsZTEXMBUGCgmSJomT8ixkARkWB3NhbWxzc28xDDAK
BgNVBAMTA2lkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ9Ai1Cs4c7CIwpJ/N0X
ub83SyYZz509A5/y65sj2iBFaIRCgzm0s+F6jCsyxpRd8fVgOtJ56CNdJkN+Zw7pOGvrD/EIvjn8
8SwCx0GDdxgtP4lfbQ7DhakSLw2hCui7yB9ijbIJjd+1f2IJbIv8TqYH4RG3kQue6i9e47W8Z4jY
URivaX/omXJvoBBBRO6a23n+jrQ7hk9KCACKfCEmlMaO9meg+mXRXyAXLnyaGw7W7qk27/7QB5uH
s2WhXIxy+wt3PrTZ9q2x413/chbQvRfrgxfhUA/GGFiWTa7x+sZ2g6bKLcGPqkjuJRuhNkeWkuOj
thnygoBz58A4f8MBqTUCAwEAAaMhMB8wHQYDVR0OBBYEFO8nqGs+aMkoBg/Ll4rbLZD9+V1mMA0G
CSqGSIb3DQEBCwUAA4IBAQAdL6/tA2faup5/BOmuBIA9CDCNk9uUf56ikFCMtP93ARsgKWPRLgba
i6tYC5qaVDOBn3Kcr0Wy3egObQsQE6lP4J7SCQUn/miBP/hogrc2uDhOuvCrBHvwGxRbhsMPUUCC
73pxGSKFf4tVKbsm8Y1k3840fJwvfc4NKn5JCj0ShEoRMmf/UkcEOTWbOEQrErrCtA3Czxo5JtKh
t8s1RPPg9p6lC5qk9Ob6tnLGh4mtHE9dc4FifMOaccCMTwc5O34jP7AM+avRcyvSw5b0jDhER8re
ubErEwK3ceaoAejlPJQbmMt9SOJfXDS7P1jc4yuWEAolJeA7CsX9xkTb3Rj3
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
</md:NameIDFormat>
<md:SingleSignOnService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://localhost/idp/SAMLResponse" />
<md:SingleSignOnService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
Location="https://localhost/idp/SAMLResponse" />
<md:SingleSignOnService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://localhost/idp/SAMLResponse" />
</md:IDPSSODescriptor>
</md:EntityDescriptor>
IdP使用BASIC身份验证对用户进行身份验证。 在本系列的第3部分中,您将了解如何配置SPNEGO身份验证。
SP发起的SSO如何工作?
以下XML文件是SP发送到IdP的身份验证请求的示例。
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="https://localhost:9443/ibm/saml20/sp/acs"
Destination="https://localhost/idp/SAMLResponse" ForceAuthn="false"
ID="_10lsWdAH1e4faN5kuKF3tY0VTVbyqXkf" IsPassive="false"
IssueInstant="2017-02-25T23:49:22.413Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
https://localhost:9443/ibm/saml20/sp
</saml2:Issuer>
<saml2p:NameIDPolicy
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" />
</saml2p:AuthnRequest>
下图显示了在SP发起的SSO中发生的通信顺序。 请注意以下几点:
对于此解决方案,您必须在WebSphere Liberty上绑定Web服务安全策略,以从客户端Web应用程序自动传播SAML令牌。 您可以在传输层或消息级别设置Web服务安全性。 在传输层,您可以基于安全套接字层(SSL)或传输层安全性(TLS)设置安全性,以保护点对点的HTTP消息内容。
如果在消息级别保护Web服务的安全,则可以保护Web服务的HTTP消息中的SOAP内容。 您可以通过在Web服务Web服务描述语言(WSDL)文档中添加策略定义来设置Web服务安全性 ,并在客户端的出站通道和服务器的入站通道上配置策略。
在我们的示例中,我们在传输层和消息级别都保护Web服务。 我们通过使用基于HTTPS的SOAP在传输层设置安全性。 为了在消息级别设置安全性,我们配置了Web服务安全性SAML令牌配置文件1.1,以便客户端可以在SOAP标头中添加SAML声明,服务器可以执行该声明。
在本部分的其余部分中,我们将配置三个简单的Java EE应用程序,如下图所示,以显示该解决方案的工作方式:
下图说明了我们本地计算机上的解决方案配置。
该解决方案基于WebSphere Application Server Liberty概要文件和SAML 2.0。 要开发和部署该解决方案,您需要一个用于Java Enterprise Edition的Eclipse IDE。 在开始之前,请安装Java SDK,然后在开发计算机上安装Eclipse和WebSphere Liberty。
安装Liberty工具时,在“确认选定的功能”窗口中,选中所有工具的复选框,包括WebSphere Application Server Migration Toolkit 。
在本教程中,我们使用以下路径:
<WLP_HOME>
C:\programs\wlp-16.0.0.3
<WLP_BIN>
C:\programs\wlp-16.0.0.3\bin
<WLP_SERVERS>
C:\programs\wlp-16.0.0.3\usr\servers
安装Liberty工具后,配置Liberty服务器运行时:
您的工作区应类似于以下示例。
示例项目可在GitHub上获得 。 您可以从此压缩文件下载完整的集合,然后将其解压缩到本地文件系统。
现在,您的工作区应类似于以下示例。
提示 :如果您选择的名称不是WebSphere Application Server Liberty ,则工作空间迁移向导会提示您选择正确的运行时,如以下窗口所示。 保留所有项目处于选中状态。 然后,在下一页上,选择您的Liberty运行时。 如果使用了正确的WebSphere Application Server Liberty名称,则不会显示该向导。
创建运行导入到工作空间中的应用程序所需的四个Liberty配置文件:
要创建配置文件:
Server
,然后单击Next 。
IdentityServer
。 然后,单击下一步 。
IdentityServer
作为“服务器名称”,然后单击“ 完成” 。 如果Liberty安装中已有服务器实例,请单击“ 新建”以创建一个新的服务器实例。
<keyStore password="passw0rd"
location="${server.output.dir}/resources/security/identitykey.jks"/>
<keyStore password="passw0rd"
location="${server.output.dir}/resources/security/frontendkey.jks"/>
<keyStore password="passw0rd"
location="${server.output.dir}/resources/security/cloudkey.jks"/>
<keyStore password="passw0rd"
location="${server.output.dir}/resources/security/localkey.jks"/>
passw0rd
用作每个服务器的默认密钥库。 首次启动每个服务器时,将使用<WLP_SERVERS>
服务器目录中的日志和其他文件夹生成以下密钥库:
<WLP_SERVERS>\IdentityServer\resources\security\
identitykey.jks <WLP_SERVERS>\FrontendServer\resources\security\
frontendkey.jks <WLP_SERVERS>\CloudServer\resources\security\
<WLP_SERVERS>\LocalServer\resources\security\
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="*" httpPort="80" httpsPort="443" id="defaultHttpEndpoint"/>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<wasJmsEndpoint enabled="false" wasJmsPort="7277" wasJmsSSLPort="7287"/>
<iiopEndpoint id="defaultIiopEndpoint" iiopPort="2810">
<iiopsOptions iiopsPort="9403" sslRef="defaultSSLConfig"/>
</iiopEndpoint>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="*" httpPort="9081" httpsPort="9444" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<wasJmsEndpoint enabled="false" wasJmsPort="7278" wasJmsSSLPort="7288"/>
<iiopEndpoint id="defaultIiopEndpoint" iiopPort="2812">
<iiopsOptions iiopsPort="9404" sslRef="defaultSSLConfig"/>
</iiopEndpoint
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="*" httpPort="9082" httpsPort="9445" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<wasJmsEndpoint enabled="false" wasJmsPort="7279" wasJmsSSLPort="7289"/>
<iiopEndpoint id="defaultIiopEndpoint" iiopPort="2813">
<iiopsOptions iiopsPort="9405" sslRef="defaultSSLConfig"/>
</iiopEndpoint>
cd <WLP_BIN>
。 installUtility install wsSecuritySaml-1.1
成功完成下载和安装后,您应该看到以下消息:
All assets were successfully installed.
Start product validation...
Product validation completed successfully.
将之前导入的项目部署到服务器上:
完成后,您的服务器视图应类似于以下示例。
IdP是可以为经过身份验证的用户生成SAML断言的应用程序。 在以下步骤中,您将配置并测试IdP。
样本身份提供程序应用程序it.ibm.liberty.sample.identityProvider-1.0_1.0.0.esa作为Liberty功能提供,您可以在本教程的可下载文件中找到该功能。
要安装该功能,请打开命令提示符,然后输入: cd <WLP_BIN>
。 然后,输入以下命令,其中<absolute-or-relative-path>
是功能文件所在的本地文件系统中的路径:
installUtility install <absolute-or-relative-path>\it.ibm.liberty.sample.identityProvider-1.0_1.0.0.esa
安装成功完成后,请重新启动Eclipse工作区以重新加载可用服务器功能的列表。
配置IdP功能,以便您可以运行它:
cd <WLP_SERVERS>\IdentityServer\resources\security\
keytool -genkey -alias idpkey -keystore samlkey.jks -dname "CN=idp,dc=samlsso,dc=sample,dc=net" -storepass idpstorepass -keypass idpkeypass -storetype jks -validity 5000 -keyalg RSA
请注意以下有关某些参数的说明 :
keytool
是JDK安装中可用的命令。 与-genkey选项一起使用时,此命令将在新的samlkey.jks密钥库中生成一个以idpkey别名引用的私钥。 -storepass
是访问samlkey.jks密钥库的密码。 -keypass
是访问idpkey条目所需的密码。 IdP需要此信息来签名将生成的SAML断言。 -dname
避免提示输入名称和组织。 <keyStore id="saml" password="idpstorepass"
location="${server.config.dir}/resources/security/samlkey.jks">
<keyEntry name="idpkey" keyPassword="idpkeypass"></keyEntry>
</keyStore>
<featureManager>
元素中: <featureManager>
[...]
<feature>identityProvider-1.0</feature>
</featureManager>
<identityProvider>
配置元素: <identityProvider issuer="samlsso.sample.net" keyAlias="idpkey" keyStoreRef="saml" hostname="localhost" port="443"/>
请注意以下说明:
identityProvider
功能仅预见了几套配置参数,以允许IdP应用程序生成一个断言,并让将在下一段中配置的SP下载idp-metadata.xml配置来设置SP。 -启动的SSO。 真正的IdP软件配置起来要复杂得多,但是运行我们的示例就足够了。 idpkey
是我们先前生成的密钥库中的密钥条目。 saml
密钥库引用是samlkey.jks keyStore元素的id
属性。 443
。 <basicRegistry realm="samlsso.sample.net" ignoreCaseForAuthentication="false">
<group name="CN=IdentityRequestors,DC=samlsso,DC=sample,DC=net">
<member name="rob"/>
<member name="max"/>
<member name="bobby"/>
<member name="alice"/>
</group>
<group name="CN=FrontendServiceUsers,DC=samlsso,DC=sample,DC=net">
<member name="max"/>
<member name="bobby"/>
<member name="alice"/>
</group>
<group name="CN=CloudServiceUsers,DC=samlsso,DC=sample,DC=net">
<member name="bobby"/>
<member name="alice"/>
</group>
<group name="CN=LocalServiceUsers,DC=samlsso,DC=sample,DC=net">
<member name="alice"/>
</group>
<user name="rob" password="passw0rd"/>
<user name="max" password="passw0rd"/>
<user name="bobby" password="passw0rd"/>
<user name="alice" password="passw0rd"/>
</basicRegistry>
<authorization-roles id="idp.roles">
<security-role name="IdentityRequestor">
<special-subject type="ALL_AUTHENTICATED_USERS"/>
</security-role>
<security-role name="Snooper">
<special-subject type="ALL_AUTHENTICATED_USERS"/>
</security-role>
</authorization-roles>
使用此配置,所有basicRegistry用户都被授权执行IdentityRequestor(保护SAMLRequest servlet)和Snooper(保护监听servlet)的角色。
IdP准备为经过身份验证的用户生成SAML断言:
http://localhost/idp/SAMLResponse
http://localhost/idp/SAMLResource
http://localhost/idp/snoop
根据标准的基于JAAS角色的授权,用户属于不同的组,以允许对资源访问进行限制。
您可以在GitHub上可下载资料的servers文件夹中找到整个server.xml配置以及密钥库。
既然已经安装了samlWeb-2.0功能,就可以对其进行配置以启用SP发起的SSO。
http://localhost/idp/SAMLResource
URL,然后单击IdpMetadata.xml以下载idp-metadata.xml文件。 将文件保存在<WLP_SERVERS>\FrontendServer\resources\security\
目录中。 <featureManager>
元素中: <featureManager>
[...]
<feature>samlWeb-2.0</feature>
<feature>wsSecuritySaml-1.1</feature>
</featureManager>
<samlWebSso20 id="sp" allowCustomCacheKey="true" authnRequestsSigned="false" createSession="true"
disableLtpaCookie="true" enabled="true" groupIdentifier="Membership" httpsRequired="true"
idpMetadata="${server.config.dir}/resources/security/idp-metadata.xml" inboundPropagation="none"
includeX509InSPMetadata="true" realmName="samlsso.sample.net" signatureMethodAlgorithm="SHA256"
wantAssertionsSigned="true" />
有关配置参数的完整说明,请参阅IBM Knowledge Center 中Liberty中的“ 配置SAML Web浏览器SSO” 。
请注意以下几点:
要测试由SP启动的SSO,请启动FrontendServer,然后在http://localhost:9080/FrontendWeb/
URL上测试由SP启动的SSO 。
要查看由SP启动的SSO序列,您可以使用浏览器的开发人员工具来跟踪网络请求。 例如,如果您使用的是Mozilla Firefox,请按F12,或选择“ 选项”菜单,然后选择“ 开发人员”以启用工具栏。 以下示例显示了我们方案中由SP启动的SSO序列。
将公共SSL证书导入到frontendkey.jks密钥库中,以允许Frontend应用程序使用HTTPS调用CloudServices。 我们从CloudServer导出公共证书,然后将其导入到FrontendServer密钥库中。
cd <WLP_SERVERS>\CloudServer\resources\security\
keytool -list -keystore cloudkey.jks -storepass passw0rd
输出类似于以下示例,其中default
是包含密钥对的KeyEntry的名称:
Keystore type: jks
Keystore provider: IBMJCE
Your keystore contains 1 entry
default, Nov 17, 2016, keyEntry,
Certificate fingerprint (SHA1): 2D:16:E2:E9:FC:C1:34:26:94:35:50:7C:0C:A4:42:15:A8:4D:BE:68
keytool -export -alias default -file CloudServer.cer -keystore cloudkey.jks -storepass passw0rd
cd ..\..\..\FrontendServer\resources\security\
keytool -import -alias cloudssl -file ..\..\..\CloudServer\resources\security\CloudServer.cer -keystore frontendkey.jks -storepass passw0rd -storetype jks -keypass cloudkeypass -noprompt
keytool -list -keystore frontendkey.jks -storepass passw0rd
最后一个命令的输出类似于以下示例:
Keystore type: jks
Keystore provider: IBMJCE
Your keystore contains 2 entries
cloudssl, Nov 17, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 2D:16:E2:E9:FC:C1:34:26:94:35:50:7C:0C:A4:42:15:A8:4D:BE:68
default, Nov 17, 2016, keyEntry,
Certificate fingerprint (SHA1): 73:4C:A6:F8:32:3F:3D:0D:87:54:2C:F0:69:74:58:64:72:C6:10:CB
密钥库现在具有两个密钥: default和cloudssl 。 您刚刚添加了cloudssl键。 首次启动FrontendServer实例时,在创建密钥库时添加了默认密钥条目。 该密钥的密码为passw0rd
,因为配置server.xml实体时,您仅提供了整个密钥库的密码。
默认密钥项是应用程序服务器用于提供TLS (例如HTTPS)的证书。 因为我们添加了新密钥,所以我们必须配置FrontendServer server.xml实体以添加具有导入CloudServer.cer文件时提供的别名和密码的新密钥库引用。
错误消息:尽管您可以将两个条目及其密码添加到默认的keyStore中,但是Liberty配置文件会发出以下错误消息:
[ERROR ] CWPKI0813E: Error while trying to initialize the keymanager for the keystore [C:/programs/wlp-16.0.0.3/usr/servers/FrontendServer/resources/security/frontendkey.jks].The private key password is not correct or the keystore has multiple private keys with different passwords.This keystore can not be used for SSL. Exception message is: [Cannot recover key].
<keyStore id="trust" password="passw0rd"
location="${server.output.dir}/resources/security/frontendkey.jks">
<keyEntry name="cloudssl" keyPassword="cloudkeypass"></keyEntry>
</keyStore>
配置完成。
None of the policy alternatives can be satisfied.
此消息来自CloudServer。 (您可以检查其日志。)此消息表示SSL握手已成功执行,并且证书配置良好。 但是,由于尚未为CloudServer配置适当的策略来管理传入的SAML断言,因此CloudServer不知道如何管理它。 启用安全性是因为EJB方法受角色保护,它声称它不能满足收到的安全性策略。
对于IdentityServer,您下载的资源材料中提供了FrontendServer的完整配置。
为CloudServer和LocalServer设置安全策略。 让我们从证书开始。 两台服务器都需要声明一个SAML文档。
http://localhost/idp/SAMLResource
URL,然后单击X509证书以下载samlsso.sample.net.cer证书。 将文件保存在<WLP_SERVERS>\IdentityServer\resources\security\samlsso.sample.net.cer
目录中。 打开命令提示符,然后将目录更改为<WLP_SERVERS>\LocalServer\resources\security\
路径。 运行以下命令:
keytool -import -alias saml -file ..\..\..\IdentityServer\resources\security\samlsso.sample.net.cer -keystore localkey.jks -storepass passw0rd -storetype jks -keypass samlpassw0rd -noprompt
keytool -export -alias default -file LocalServer.cer -keystore localkey.jks -storepass passw0rd
cd ..\..\..\CloudServer\resources\security
keytool -import -alias saml -file ..\..\..\IdentityServer\resources\security\samlsso.sample.net.cer -keystore cloudkey.jks -storepass passw0rd -storetype jks -keypass samlpassw0rd -noprompt
keytool -import -alias localssl -file ..\..\..\LocalServer\resources\security\LocalServer.cer -keystore cloudkey.jks -storepass passw0rd -storetype jks -keypass localkeypass -noprompt
keytool -list -keystore cloudkey.jks -storepass passw0rd
最后一个命令显示CloudServer的三个证书。 您可以对LocalServer运行相同的命令,但仅显示前两个键。
Keystore type: jks
Keystore provider: IBMJCE
Your keystore contains 3 entries
saml, Nov 17, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 8B:EC:92:91:2E:12:57:7B:B4:DC:4A:A6:7C:3A:E7:AE:D9:11:CC:5A
default, Nov 17, 2016, keyEntry,
Certificate fingerprint (SHA1): 2D:16:E2:E9:FC:C1:34:26:94:35:50:7C:0C:A4:42:15:A8:4D:BE:68
localssl, Nov 18, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): A4:3E:2E:94:9A:E0:E8:04:65:46:43:89:AA:EF:99:6B:9D:A7:06:AF
现在,您已经完成了两个服务器的导入。
<featureManager>
[...]
<feature>wsSecuritySaml-1.1</feature>
</featureManager>
<keyStore id="trust" password="passw0rd" location="${server.output.dir}/resources/security/cloudkey.jks">
<keyEntry name="localssl" keyPassword="localkeypass"></keyEntry>
<keyEntry name="saml" keyPassword="samlpassw0rd"></keyEntry>
</keyStore>
<wsSecurityProvider id="SAMLBearerSSL">
<samlToken clockSkew="5m" requiredSubjectConfirmationMethod="bearer" timeToLive="30m"
wantAssertionsSigned="true"/>
<callerToken groupIdentifier="Membership" mapToUserRegistry="No" name="SAMLtoken"/>
<signatureProperties org.apache.ws.security.crypto.merlin.keystore.alias="samlsso.sample.net"
org.apache.ws.security.crypto.merlin.keystore.type="jks"
org.apache.ws.security.crypto.merlin.file="${server.output.dir}/resources/security/cloudkey.jks"
org.apache.ws.security.crypto.merlin.keystore.password="passw0rd"
org.apache.ws.security.crypto.merlin.keystore.private.password="samlpassw0rd"/>
</wsSecurityProvider>
现在,您已经完成了CloudServer的操作 。
提示 :根据用户的组,您是否可以访问该服务。 如果您以bobby
或alice
身份登录到IdP,您将被授权并看到如下示例所示的答复:
service response: Response from CloudMessageService.getMessage at 1479426017208
otherwise following message should appear:
java.rmi.AccessException: ; nested exception is: com.ibm.websphere.csi.CSIAccessException:
CWWKS9400A: Authorization failed for user max while invoking getMessage on CloudServices.
The user is not granted access to any of the required roles: [CloudServiceAccessRole].
<keyStore id="trust" password="passw0rd" location="${server.output.dir}/resources/security/localkey.jks">
<keyEntry name="saml" keyPassword="samlpassw0rd"></keyEntry>
</keyStore>
<wsSecurityProvider id="SAMLBearerSSL">
<samlToken clockSkew="5m" requiredSubjectConfirmationMethod="bearer" timeToLive="30m"
wantAssertionsSigned="true"/>
<callerToken groupIdentifier="Membership" mapToUserRegistry="No" name="SAMLtoken"/>
<signatureProperties org.apache.ws.security.crypto.merlin.keystore.alias="samlsso.sample.net"
org.apache.ws.security.crypto.merlin.keystore.type="jks"
org.apache.ws.security.crypto.merlin.file="${server.output.dir}/resources/security/localkey.jks"
org.apache.ws.security.crypto.merlin.keystore.password="passw0rd"
org.apache.ws.security.crypto.merlin.keystore.private.password="samlpassw0rd"/>
</wsSecurityProvider>
现在,您已经完成了LocalServer。
提示 :根据用户的组,您是否可以访问该服务。 如果您以alice
身份登录到IdP,那么您将获得授权,并且可以看到LocalServer上的Web服务发出的消息,该消息由CloudServer调用(由前端servlet调用),如以下示例所示:
service response: Response from LocalMessageService.getLocalMessage at 1479426200968
否则,您会看到以下消息:
java.rmi.AccessException: ; nested exception is: com.ibm.websphere.csi.CSIAccessException:
CWWKS9400A: Authorization failed for user bobby while invoking getLocalMessage on LocalServices.
The user is not granted access to any of the required roles: [LocalServiceAccessRole].
就像FrontendServer配置一样,可在server文件夹中的资源资料中找到CloudServer和LocalServer配置。
现在,您在本地计算机上具有基于WebSphere Application Server Liberty概要文件和SAML 2.0的功能齐全的,端到端SP启动的SSO。 您还在WebService应用程序之间传播了SAML身份。 您可以在GitHub上的代码示例中查看本教程,以了解其工作原理。
在第2部分中 ,您将在IBM Cloud中部署FrontendServer和CloudServer。 您还配置安全网关,以允许CloudServices应用程序访问由LocalServices应用程序公开的Web服务,该服务仍在私有网络上运行,而该私有网络无法从作为本地计算机的公共Internet访问。 Then, in Part 3 , you extend the SSO scenario to integrate the Microsoft Windows authentication, by using the Simple and Protected GSS-API Negotiation Mechanism (SPNEGO) and the Active Directory Domain Services.
The authors thank Massimo Leoni , Carlo Randone , and Richard Kozel for reviewing this article and providing helpful comments, and Pavel Travnik for testing the code.
翻译自: https://www.ibm.com/developerworks/library/mw-1703-maurip1-bluemix/index.html
sso 服务端配置
今天更新一个小节内容,这个小节是改错专项练习。希望能和大家一起努力,共同进步~
--------------------------------------------------------------------------------------------------------------------------------------------------------(1)屏幕尺寸计算:通常说屏幕是多少寸的,寸是“英寸”这个单位。屏幕的尺寸是指屏幕对
1.原理最远点采样2.Python实现import randomimport mathimport matplotlib.pyplot as pltM = 50 # 所有的点数量N = 10 # fps采样点数量x = []y = []xy = []# 生成数据random.seed(0)for _ in range(M): px = round(random...
Windows Server2012 安装配置DNS服务器方法详解在云服务器 Windows Server2012 上安装配置DNS服务器方法,安装与配置非常简单,在这里写个完整教程方便大家查询一、安装DNS服务器1.打开服务器管理器,点击添加角色和功能2.一直下一步,选择基于角色或基于功能的安装3.选择目标服务器,只有一台4.添加DNS服务器5.一直下一步直到安装成功二、配置DNS服务器之前安装...
8# 发表于:2018-10-11 09:25:33 IP:183.175.*.*回复第7楼您好!昨晚安装了你发的修复包。还是报空指针异常,只是报错的方法跟昨天的有一点查别。麻烦看下查看日志如下:[2018-10-1109:06:05上午]:ERRORcom.jeecms.cms.entity.main.Channel.getStaticChannel(Channel.java:1324...
idea 中的gitee出现 Incorrect credentials. Request response: 401 Unauthorized 如图网上有的人说是邮箱没绑定,也有人说修改一下密码就好了,我则是…Login:不是账号,而是 @里面的东西, 不包括@符号...
原文地址: http://guiliblearning.blogspot.com/2009/05/gtkmm-vs-qt.html作者: demonstrateGtkmm 自己的手册上也对 Qt 进行了比较,另外在 FAQ 里面也有所阐述,我们在这里记录一下:Qt 产生的时代比较早,那个时候 C++ 标准尚未成熟,而 Gtkmm 产生较晚,那个时候 C++ 标准和 STL 都比较成熟。
类图工程目录代码AbstractSubject.javapackage com.company.pattern.demo04;/** * 定义了RealSubject和Proxy的共用接口,这样就可以在任何使用RealSubject的地方使用Proxy * @author blazar */public abstract class AbstractSubject { /** * 请求方法 */ public abstract void reque
学习过程,记录一下。 这段时间学习Quick2在自己定义一个按钮时想做一个效果,鼠标悬停在按钮上时按钮背景显示一种颜色,鼠标离开时回复原样。 刚开始是代码是这样的:Rectangle{ color:"green" width: 28 height: 28
1. 私有属性添加getter和setter方法class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self, value): if isinsta...
题目描述某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少)。老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯。为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯...
网络通信之Socket与LocalSocket的比较https://www.shuzhiduo.com/A/gVdnmBKQ5W/理解Socket是网络通信的套接字实现; LocalSocket是Android用于系统内跨进程通信的实现. 都基于Client和Server模式进行通信.