我正在测试使用自定义 STS 服务验证使用的产品。它过去的工作方式是,当用户使用浏览器访问网站时,我们会发出重定向以访问 STS 服务。STS 服务通过点击 AD 对用户进行身份验证,然后为用户发出带有一些自定义声明的 SAML 令牌。然后该网站再次访问 STS 以获取 ActAs 令牌,以便我们可以与数据服务进行通信。
我有一个可以模仿这种行为的自动化系统,并且它在生产中运行良好。
我们不会修改 STS 以使用 ADFS 进行身份验证,而不是直接点击 AD。所以现在当我访问网站时,请求被重定向到 ADFS 端点,该端点对用户进行身份验证并发出令牌。然后我们点击自定义 STS 服务,该服务将使用令牌对用户进行身份验证(而不是点击 AD),添加自定义声明并为用户发出 SAML 令牌。然后,我们使用它生成一个 ActAs 令牌以最终命中数据服务。
我正在尝试针对这种改变的行为更新我的自动化。所以我现在要做的是访问 ADFS 服务,获取令牌并将令牌传递给 STS 服务,以便它可以向我发出 SAML 令牌。
在 Windows 身份服务方面,我是一个相当业余的人,所以我很难尝试完成这项工作。我已成功从 ADFS 获得令牌(不记名令牌),但我无法弄清楚如何将此令牌传递给我的自定义 STS,以便它可以向我发出 SAML 令牌。
任何帮助将不胜感激。谢谢!
这是我正在使用的代码
public static SecurityToken GetSecurityToken()
{
var endPoint = new EndpointAddress(new Uri(@"ADFS endpoint"));
var msgBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
msgBinding.Security.Message.EstablishSecurityContext = false;
msgBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var factory = new WSTrustChannelFactory(msgBinding, endPoint);
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.SupportInteractive = true;
factory.Credentials.UserName.UserName = "user";
factory.Credentials.UserName.Password = "pwd";
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Bearer,
AppliesTo = new EndpointReference(@"custom STS endpoint")
};
return factory.CreateChannel().Issue(rst);
}
public static void GetUserClaimsFromSecurityTokenService(SecurityToken secToken)
{
var securityTokenManager = new SecurityTokenHandlerCollectionManager(string.Empty);
securityTokenManager[string.Empty] = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
var trustChannelFactory = new WSTrustChannelFactory(Binding, new EndpointAddress("custom STS endpoint"))
{
TrustVersion = TrustVersion.WSTrust13,
SecurityTokenHandlerCollectionManager = securityTokenManager,
};
var rst = new RequestSecurityToken(RequestTypes.Issue)
{
AppliesTo = new EndpointReference("website url"),
TokenType = SamlSecurityTokenHandler.Assertion
};
var channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
channel.Open(TimeSpan.FromMinutes(15));
try
{
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
var genericToken = (GenericXmlSecurityToken)token;
var req = new SamlSecurityTokenRequirement();
var handler = new SamlSecurityTokenHandler(req)
{
Configuration = new SecurityTokenHandlerConfiguration()
};
var newToken = handler.ReadToken(new XmlNodeReader(genericToken.TokenXml));
}
finally
{
channel.Close();
}
}