【问题标题】:SecurityNegotiationException - Retrieving token from web serviceSecurityNegotiationException - 从 Web 服务中检索令牌
【发布时间】:2020-12-11 01:19:54
【问题描述】:

我正在尝试从 WIF 3.5 迁移到 WIF 4.5。然而,事实证明,转换比我预期的要困难得多。问题将与代码中的 cmets 相对应。

完整的错误信息:

System.Web.Services.Protocols.SoapException: 'System.Web.Services.Protocols.SoapException: 身份验证失败 --->

System.ServiceModel.Security.SecurityNegotiationException:安全 无法打开通道,因为与远程的安全协商 端点失败。这可能是由于缺席或不正确 EndpointAddress 中指定的 EndpointIdentity 用于创建 渠道。请验证指定或暗示的 EndpointIdentity EndpointAddress 正确识别远程端点。

无法打开安全通道,因为与 远程端点失败。这可能是由于缺席或不正确 EndpointAddress 中指定的 EndpointIdentity 用于创建 渠道。请验证指定或暗示的 EndpointIdentity EndpointAddress 正确识别远程端点。

#1。需要哪个用户名/密码组合,哪个不需要?

#2。这是抛出 SecurityNegotiationException 的地方。我到底错过了什么?

那么,我是不是很遥远,还是我缺少一些简单的东西?我是否需要完全重写 WSTrustChannelFactory 的创建方式?

代码:

public string GetToken(string url, string domain, string realm, string username, string password)
{
    string rp = realm;
    string token = "";

    WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory
    (
        new WSHttpBinding(SecurityMode.TransportWithMessageCredential),
        new EndpointAddress(new Uri(url))
    );
        
    trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
    trustChannelFactory.Credentials.Windows.ClientCredential.Domain = domain;
    trustChannelFactory.Credentials.Windows.ClientCredential.UserName = username; // #1; not sure which pair is needed?
    trustChannelFactory.Credentials.Windows.ClientCredential.Password = password;

    trustChannelFactory.Credentials.UserName.Password = password;
    trustChannelFactory.Credentials.UserName.UserName = username;

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    try
    {
        RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue, KeyTypes.Bearer);
        rst.AppliesTo = new EndpointReference(rp);
        rst.TokenType = SecurityTokenTypes.Saml;

        WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
        GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken; // #2; Exception thrown here
        token = token.TokenXml.OuterXml;
    }
    catch (SecurityNegotiationException e)
    {
        LogError("Authentication Failed", e);
    }
    catch (TimeoutException e)
    {
        LogError("Unable to authenticate", e);
    }
    catch (CommunicationException e)
    {
        LogError("Communication exception", e);
    }
    catch (Exception e)
    {
        LogError("Unknown exception", e);
    }
    return token;
}

【问题讨论】:

    标签: c# web-services adfs wif


    【解决方案1】:

    我们决定暂时继续使用 WIF 3.5,并将对 WIF 4.5 进行全面重写,而不是尝试做一些不可能的事情。

    更改太多,文档不足,无法将我们现有的代码从 WIF 3.4 升级到 WIF 4.5

    【讨论】:

      【解决方案2】:

      您需要使用 SecurityTokenHandlerCollection

              public SecurityToken GetToken(string url, string realm, string username, string password)
              {
                  string rp = realm;
              
                  WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential, false);
      
                  binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
                  binding.Security.Message.EstablishSecurityContext = false;
      
                  EndpointAddress endpoint = new EndpointAddress(url);
      
                  WSTrustChannelFactory factory = new WSTrustChannelFactory(binding, endpoint);
                  factory.TrustVersion = TrustVersion.WSTrust13;
      
                  factory.Credentials.UserName.UserName = username;
                  factory.Credentials.UserName.Password = password;
      
                  WSTrustChannel channel = (WSTrustChannel) factory.CreateChannel();
      
                  RequestSecurityToken rst = new RequestSecurityToken
                  {
                      RequestType = RequestTypes.Issue,
                      KeyType = KeyTypes.Bearer,
                      AppliesTo = new EndpointReference(rp),              
                      TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
                  };
      
                  GenericXmlSecurityToken genericXmlSecurityToken = (GenericXmlSecurityToken) channel.Issue(rst, out RequestSecurityTokenResponse rstr);          
      
                  SecurityTokenHandlerCollection tokenHandlers = new SecurityTokenHandlerCollection(
                      new SecurityTokenHandler[]
                      {
                          new SamlSecurityTokenHandler(), 
                          new Saml2SecurityTokenHandler()
                      }
                  );
                  tokenHandlers.Configuration.AudienceRestriction = new AudienceRestriction();
                  tokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(rp));
      
                  TrustedIssuerNameRegistry trustedIssuerNameRegistry = new TrustedIssuerNameRegistry();
                  tokenHandlers.Configuration.IssuerNameRegistry = trustedIssuerNameRegistry;
      
                  SecurityToken token =
                      tokenHandlers.ReadToken(
                          new XmlTextReader(new StringReader(genericXmlSecurityToken.TokenXml.OuterXml)));
      
                  return token;
              }
      
              public class TrustedIssuerNameRegistry : IssuerNameRegistry
              {
                  public override string GetIssuerName(SecurityToken securityToken)
                  {
                      return "Trusted Issuer";
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-09
        • 1970-01-01
        • 2019-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多