2017-07-28 67 views
1

question about using SAML in ASP.Net Core,但我需要额外的帮助。ASP.Net Core - 将SAML断言转化为ClaimsPrincipal

那里唯一的答案提到Kentor.AuthServices,但我不明白如何使用它。我在这个或其他SAML库,文档,博客文章和示例应用程序中找到的所有内容都与联系某些外部认证服务以及处理登录和注销有关。

但我不需要这些。我正在使用的设置在面向边缘的防火墙应用程序中执行,并且登录/注销请求永远不会到达我的应用程序。我得到的只是一个Cookie中的SAML令牌,我需要验证它并将其转换为ClaimsPrincipal。我不能(部署网络设置是疯狂的偏执狂),并且不想联系任何身份提供者。

目前我写了一段中间件,它接受cookie,解析它,并解析出声明主体需要的部分。但是我不做任何验证,无论是XML签名还是SAML有效性(有效时间属性等)。使用.Net Core 2.0 Preview 2我可以执行XML签名验证,但我仍然坚持进行SAML验证。有没有一个库可以简单地验证SAML约束,而且什么也不做(或者至少在我可以忽略的地方)?我相信Kentor或ITfoxtec或elerch的SAML2.Core必须包含这样的功能,但我无法弄清楚它在哪里。

回答

1

我已经在System.IdentityModel.Tokens 中使用了SecurityTokenHandlerCollection类,我希望这段代码能够帮到你。

public Saml2SecurityToken DeserializeSAMLResponse(string samlResponse) 
    { 
     //Deserializing saml response 

     Saml2SecurityToken token; 
     using (var reader = XmlReader.Create(new StringReader(samlResponse))) 
     { 
      reader.ReadToFollowing("Assertion", Infrastructure.Enumerations.StringEnum.GetStringValue(SAMLProtocoles.SAML_20_ASSERTION)); 
      // Deserialize the token so that data can be taken from it and plugged into the RSTR 
      SecurityTokenHandlerCollection tokenHandlerCollection = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(); 
      token = (Saml2SecurityToken)tokenHandlerCollection.ReadToken(reader.ReadSubtree()); 
     } 

     //Deserializing successful 
     return token; 
    } 

它会在内部验证SAML和解析它在Saml2SecurityToken 后你得到的令牌,你可以将用户凭据这样

public User ReadSamlResponse(string samlResponse, string profileName, bool isSAMLProfile = true) 
    { 
     User User = new User(); 
     var DecodedSamlResponse = Convert.FromBase64String(samlResponse); 
     string ResponseDecoded = coding.UTF8.GetString(DecodedSamlResponse); 

      Saml2SecurityToken Token = _samlAuthenticationService.DeserializeSAMLResponse(ResponseDecoded); 
      if()// apply condition here if you need to validate signature 
      { 
       if (!_samlAuthenticationService.ValidateSamlToken(ResponseDecoded, AuthenticationConnector, isSAMLProfile)) 
        throw new Exception("Signature is invalid"); 
      } 

      User = GetUserFromToken(Token); 
      return User; 
     } 

并获得用户的安全令牌,你可以这样做

public User GetUserFromToken(Saml2SecurityToken Token) 
    { 
     //Get user information from the token started 
     User User = new User(); 
     if (Token != null) 
     { 
      if (Token.Assertion.Subject.NameId != null && (Token.Assertion.Subject.NameId.Format == null || Token.Assertion.Subject.NameId.Format.OriginalString == "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")) 
       User.EmailAddress = Token.Assertion.Subject.NameId.Value; 
      foreach (var Statement in Token.Assertion.Statements) 
      { 
       var AttributeStatement = Statement as Saml2AttributeStatement; 
       var AuthenticationStatement = Statement as Saml2AuthenticationStatement; 
       if (AttributeStatement != null) 
        foreach (var Saml2Attribute in AttributeStatement.Attributes) 
        { 
         if (Saml2Attribute.Name.Equals("mail") || Saml2Attribute.Name.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")) 
          User.EmailAddress = Saml2Attribute.Values[0]; 
         if (Saml2Attribute.Name.Equals("uid") || Saml2Attribute.Name.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")) 
          User.Name = Saml2Attribute.Values[0]; 
         if (Saml2Attribute.Name.Equals("phone")) 
          User.MobileNumber = Saml2Attribute.Values[0]; 
         if (Saml2Attribute.Name.Equals("title")) 
          User.JobTitle = Saml2Attribute.Values[0]; 
         if (Saml2Attribute.Name.Equals("company")) 
          User.CompanyName = Saml2Attribute.Values[0]; 
        } 
       if (AuthenticationStatement != null) 
       { 
        User.SAMLSessionIndex = AuthenticationStatement.SessionIndex; 
       } 
      } 
     } 
     //Successfully parsed user credentials 
     return User; 
    }