2017-07-28 80 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; 
    }