private static void getAttributeValues(ResponseType response, Dictionary <String, List <LinkIDAttribute> > attributeMap) { if (null == response.Items || response.Items.Length == 0) { throw new RuntimeException("No assertions in response"); } AssertionType assertion = (AssertionType)response.Items[0]; if (null == assertion.Items || assertion.Items.Length == 0) { throw new RuntimeException("No statements in response assertion"); } AttributeStatementType attributeStatement = (AttributeStatementType)assertion.Items[0]; foreach (Object attributeObject in attributeStatement.Items) { AttributeType attributeType = (AttributeType)attributeObject; LinkIDAttribute attribute = Saml2AuthUtil.getAttribute(attributeType); List <LinkIDAttribute> attributes; if (!attributeMap.ContainsKey(attribute.attributeName)) { attributes = new List <LinkIDAttribute>(); } else { attributes = attributeMap[attribute.attributeName]; } attributes.Add(attribute); attributeMap.Remove(attribute.attributeName); attributeMap.Add(attribute.attributeName, attributes); } }
public AssertionData(AssertionType assertion) { // Find the attribute statement within the assertion AttributeStatementType ast = null; foreach (StatementAbstractType sat in assertion.Items) { if (sat.GetType().Equals(typeof(AttributeStatementType))) { ast = (AttributeStatementType)sat; } } if (ast == null) { throw new ApplicationException("Invalid SAML Assertion: Missing Attribute Values"); } SAMLAttributes = new Dictionary <string, string>(); // Do what needs to be done to pull specific attributes out for sending on // For now assuming this is a simple list of string key and string values foreach (AttributeType at in ast.Items) { SAMLAttributes.Add(at.Name, ((XmlNode[])at.AttributeValue[0])[1].Value); } }
public static LinkIDAuthnResponse parse(ResponseType response) { String userId = null; Dictionary <String, List <LinkIDAttribute> > attributes = new Dictionary <string, List <LinkIDAttribute> >(); foreach (object item in response.Items) { AssertionType assertion = (AssertionType)item; SubjectType subject = assertion.Subject; NameIDType nameId = (NameIDType)subject.Items[0]; userId = nameId.Value; foreach (StatementAbstractType statement in assertion.Items) { if (statement is AttributeStatementType) { AttributeStatementType attributeStatement = (AttributeStatementType)statement; attributes = getAttributes(attributeStatement); } } } LinkIDPaymentResponse paymentResponse = findPaymentResponse(response); LinkIDExternalCodeResponse externalCodeResponse = findExternalCodeResponse(response); return(new LinkIDAuthnResponse(userId, attributes, paymentResponse, externalCodeResponse)); }
public AssertionData(AssertionType assertion) { // Find the attribute statement within the assertion AttributeStatementType ast = null; foreach (StatementAbstractType sat in assertion.Items) { if (sat.GetType().Equals(typeof(AttributeStatementType))) { ast = (AttributeStatementType)sat; } } if (ast == null) { throw new ApplicationException("Invalid SAML Assertion: Missing Attribute Values"); } SAMLAttributes = new Dictionary <string, string>(); // Do what needs to be done to pull specific attributes out for sending on // For now assuming this is a simple list of string key and string values foreach (AttributeType at in ast.Items) { SAMLAttributes.Add(at.Name, at.AttributeValue.ToString()); //switch (at.Name) //{ // case "UserID": // if (at.AttributeValue.Length > 0) UserID = at.AttributeValue[0].ToString(); // break; // case "UserFirstName": // if (at.AttributeValue.Length > 0) UserFirstName = int.Parse(at.AttributeValue[0].ToString()); // break; // case "UserLastName": // if (at.AttributeValue.Length > 0) UserLastName = at.AttributeValue[0].ToString(); // break; // case "UserDisplayName": // if (at.AttributeValue.Length > 0) UserDisplayName = at.AttributeValue[0].ToString(); // break; // case "UserEmail": // if (at.AttributeValue.Length > 0) UserEmail = at.AttributeValue[0].ToString(); // break; // case "GroupID": // if (at.AttributeValue.Length > 0) GroupID = int.Parse(at.AttributeValue[0].ToString()); // break; //} } }
/// <summary> /// Express particular attributes and values associates with an assertion subject. /// </summary> /// <param name="name">The name of the attribute.</param> /// <param name="nameFormat">Classification of the attribute name.</param> /// <param name="valueType">Data type</param> /// <param name="value">Value</param> /// <returns></returns> public AssertionBuilder AddAttributeStatementAttribute(string name, string nameFormat, string valueType, string value) { if (_assertion.Items == null) { _assertion.Items = new StatementAbstractType[0]; } var attributeStatement = _assertion.Items.FirstOrDefault(i => i is AttributeStatementType) as AttributeStatementType; if (attributeStatement == null) { attributeStatement = new AttributeStatementType(); _assertion.Items = _assertion.Items.Add(attributeStatement); } var attributes = new List <object>(); if (attributeStatement.Items != null) { attributes = attributeStatement.Items.ToList(); } var attribute = attributes.FirstOrDefault(a => a is AttributeType && ((AttributeType)a).Name == name) as AttributeType; if (attribute == null) { attribute = new AttributeType { Name = name, NameFormat = nameFormat }; attributes.Add(attribute); } var values = new ArrayList(); if (attribute.AttributeValue != null) { values = attribute.AttributeValue; } values.Add(value); attribute.AttributeValue = values; attributeStatement.Items = attributes.ToArray(); return(this); }
private static Dictionary <string, List <LinkIDAttribute> > getAttributes(AttributeStatementType attributeStatement) { Dictionary <string, List <LinkIDAttribute> > attributeMap = new Dictionary <string, List <LinkIDAttribute> >(); foreach (object item in attributeStatement.Items) { AttributeType attributeType = (AttributeType)item; LinkIDAttribute attribute = getAttribute(attributeType); List <LinkIDAttribute> attributes; if (!attributeMap.ContainsKey(attribute.attributeName)) { attributes = new List <LinkIDAttribute>(); } else { attributes = attributeMap[attribute.attributeName]; } attributes.Add(attribute); attributeMap.Remove(attribute.attributeName); attributeMap.Add(attribute.attributeName, attributes); } return(attributeMap); }
private static AssertionType CreateSamlAssertion(AuthnRequestType samlAuthRequest, string username) { var assertion = new AssertionType { Version = "2.0", IssueInstant = DateTime.UtcNow, ID = "_" + Guid.NewGuid(), Issuer = new NameIDType() { Value = $"{_context.Request.Scheme}://{_context.Request.Host}{_context.Request.PathBase}" } }; //Assertion Subject var subject = new SubjectType(); var subjectNameIdentifier = new NameIDType() { Value = username, Format = Saml2Constants.NameIdentifierFormats.Unspecified }; var subjectConfirmation = new SubjectConfirmationType() { Method = Saml2Constants.SubjectConfirmationMethods.HolderOfKey, SubjectConfirmationData = new SubjectConfirmationDataType() { NotOnOrAfter = DateTime.UtcNow.AddMinutes(ASSERTION_TIMEOUT_IN_MINUTES), Recipient = samlAuthRequest.AssertionConsumerServiceURL, InResponseTo = samlAuthRequest.ID } }; subject.Items = new object[] { subjectNameIdentifier, subjectConfirmation }; assertion.Subject = subject; //Assertion Conditions var conditions = new ConditionsType { NotBefore = DateTime.UtcNow, NotBeforeSpecified = true, NotOnOrAfter = DateTime.UtcNow.AddMinutes(ASSERTION_TIMEOUT_IN_MINUTES), NotOnOrAfterSpecified = true, //TODO: samlAuthRequest.Issuer.Value should be replaced with Items = new ConditionAbstractType[] { new AudienceRestrictionType() { Audience = new string[] { samlAuthRequest.Issuer.Value } } } }; assertion.Conditions = conditions; //Assertion AuthnStatement var authStatement = new AuthnStatementType() { AuthnInstant = DateTime.UtcNow, SessionIndex = assertion.ID }; var context = new AuthnContextType(); context.ItemsElementName = new[] { ItemsChoiceType5.AuthnContextClassRef }; context.Items = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" }; authStatement.AuthnContext = context; //Assertion AttributeStatement var attributeStatement = new AttributeStatementType(); attributeStatement.Items = new AttributeType[] { //Add as many attributes as you want here, these are the user details that service provider wants, we can customise the attributes required // on the basis of service provider that requires this assertion new AttributeType { Name = "username", AttributeValue = username, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic" } }; assertion.Items = new StatementAbstractType[] { authStatement, attributeStatement }; return(assertion); }
public SamlUser Map(ResponseType response) { SamlUser user = new SamlUser(); AssertionType assertion = response.Items.OfType <AssertionType>().FirstOrDefault(); if (assertion != null) { AttributeStatementType attributeStatement = assertion.Items.OfType <AttributeStatementType>().FirstOrDefault(); if (attributeStatement != null) { foreach (AttributeType attribute in attributeStatement.Items.OfType <AttributeType>()) { switch (attribute.Name) { case "spidCode": user.SpidCode = attribute.AttributeValue[0].ToString(); break; case "IdUtente": user.IdUser = attribute.AttributeValue[0].ToString(); break; case "nome": user.Name = attribute.AttributeValue[0].ToString(); break; case "cognome": user.Surname = attribute.AttributeValue[0].ToString(); break; case "sesso": user.Gender = attribute.AttributeValue[0].ToString(); break; case "ivaCode": user.IvaCode = attribute.AttributeValue[0].ToString(); break; case "companyName": user.CompanyName = attribute.AttributeValue[0].ToString(); break; case "cellulare": user.MobilePhone = attribute.AttributeValue[0].ToString(); break; case "address": user.Address = attribute.AttributeValue[0].ToString(); break; case "CodiceFiscale": user.FiscalNumber = attribute.AttributeValue[0].ToString(); break; case "dataNascita": user.DateOfBirth = attribute.AttributeValue[0].ToString(); break; case "provinciaNascita": user.CountyOfBirth = attribute.AttributeValue[0].ToString(); break; case "luogoNascita": user.PlaceOfBirth = attribute.AttributeValue[0].ToString(); break; case "idCard": user.IdCard = attribute.AttributeValue[0].ToString(); break; case "registeredOffice": user.RegisteredOffice = attribute.AttributeValue[0].ToString(); break; case "emailAddress": user.PEC = attribute.AttributeValue[0].ToString(); break; case "emailAddressPersonale": user.Email = attribute.AttributeValue[0].ToString(); break; case "expirationDate": user.ExpirationDate = attribute.AttributeValue[0].ToString(); break; case "digitalAddress": user.DigitalAddress = attribute.AttributeValue[0].ToString(); break; default: break; } } } } return(user); }
private SamlBodyResponse ProcessResponse(SamlBodyResponse samlBodyRes, XmlDocument xml, XmlReader reader) { // desserializar xml para ResponseType XmlSerializer serializer = new XmlSerializer(typeof(ResponseType)); ResponseType response = (ResponseType)serializer.Deserialize(reader); // verificar validade temporal: int validTimeFrame = 5; if (Math.Abs(response.IssueInstant.Subtract(DateTime.UtcNow).TotalMinutes) > validTimeFrame) { return(AddResponseError(samlBodyRes, "SAML Response fora do intervalo de validade - validade da resposta: " + response.IssueInstant)); } samlBodyRes.RelayState = Encoding.UTF8.GetString(Convert.FromBase64String(samlBodyRes.RelayState)); if ("urn:oasis:names:tc:SAML:2.0:status:Success".Equals(response.Status.StatusCode.Value)) { AssertionType assertion = new AssertionType(); for (int i = 0; i < response.Items.Length; i++) { if (response.Items[i].GetType() == typeof(AssertionType)) { assertion = (AssertionType)response.Items[i]; break; } } // validade da asserção: DateTime now = DateTime.UtcNow; TimeSpan tSpan = new TimeSpan(0, 0, 150); // 2,5 minutos if (now < assertion.Conditions.NotBefore.Subtract(tSpan) || now >= assertion.Conditions.NotOnOrAfter.Add(tSpan)) { // Asserção inválida return(AddResponseError(samlBodyRes, "Asserções temporalmente inválidas.")); } AttributeStatementType attrStatement = new AttributeStatementType(); for (int i = 0; i < assertion.Items.Length; i++) { if (assertion.Items[i].GetType() == typeof(AttributeStatementType)) { attrStatement = (AttributeStatementType)assertion.Items[i]; break; } } foreach (object obj in attrStatement.Items) { AttributeType attr = (AttributeType)obj; samlBodyRes.IdentityAttributes = new Dictionary <string, string>(); if (attr.AnyAttr != null) { for (int i = 0; i < attr.AnyAttr.Length; i++) { XmlAttribute xa = attr.AnyAttr[i]; if (xa.LocalName.Equals("AttributeStatus") && xa.Value.Equals("Available")) { if (attr.AttributeValue != null && attr.AttributeValue.Length > 0) { foreach (var itemAttr in attr.AttributeValue) { samlBodyRes.IdentityAttributes.Add((string)attr.Name, (string)attr.AttributeValue[0]); } } } } } } } else { //bad result if (response.Status.StatusMessage.Equals("urn:oasis:names:tc:SAML:2.0:status:AuthnFailed (User has canceled the process of obtaining attributes).")) { return(AddResponseError(samlBodyRes, "Autenticação não autorizada pelo utilizador")); } return(AddResponseError(samlBodyRes, "urn:oasis:names:tc:SAML:2.0:status:" + response.Status.StatusCode.Value)); } samlBodyRes.Success = true; samlBodyRes.Action = Enums.SamlResponseAction.Login; var strCipher = new StringCipher(); System.Globalization.CultureInfo cultureinfo = new System.Globalization.CultureInfo("pt-PT"); var tokenDateValid = DateTime.UtcNow.AddSeconds(TokenTimeValueConfig).ToString(cultureinfo); samlBodyRes.AuthToken = strCipher.Encrypt($"{samlBodyRes.IdentityAttributes.FirstOrDefault().Value}%{tokenDateValid}"); return(samlBodyRes); }
/// <summary> /// Creates a Version 1.1 Saml Assertion /// </summary> /// <param name="issuer">Issuer</param> /// <param name="subject">Subject</param> /// <param name="attributes">Attributes</param> /// <returns>returns a Version 1.1 Saml Assertoion</returns> private static AssertionType CreateSaml11Assertion(string issuer, string domain, string subject, Dictionary <string, string> attributes) { // Create some SAML assertion with ID and Issuer name. AssertionType assertion = new AssertionType(); assertion.AssertionID = "_" + Guid.NewGuid().ToString(); assertion.Issuer = issuer.Trim(); assertion.MajorVersion = "1"; assertion.MinorVersion = "1"; assertion.IssueInstant = System.DateTime.UtcNow; //Not before, not after conditions ConditionsType conditions = new ConditionsType(); conditions.NotBefore = DateTime.UtcNow; conditions.NotBeforeSpecified = true; conditions.NotOnOrAfter = DateTime.UtcNow.AddMinutes(10); conditions.NotOnOrAfterSpecified = true; //Name Identifier to be used in Saml Subject NameIdentifierType nameIdentifier = new NameIdentifierType(); nameIdentifier.NameQualifier = domain.Trim(); nameIdentifier.Value = subject.Trim(); SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType(); subjectConfirmation.ConfirmationMethod = new string[] { "urn:oasis:names:tc:SAML:1.0:cm:bearer" }; // // Create some SAML subject. SubjectType samlSubject = new SubjectType(); AttributeStatementType attrStatement = new AttributeStatementType(); AuthenticationStatementType authStatement = new AuthenticationStatementType(); authStatement.AuthenticationMethod = "urn:oasis:names:tc:SAML:1.0:am:password"; authStatement.AuthenticationInstant = System.DateTime.UtcNow; samlSubject.Items = new object[] { nameIdentifier, subjectConfirmation }; attrStatement.Subject = samlSubject; authStatement.Subject = samlSubject; IPHostEntry ipEntry = Dns.GetHostEntry(System.Environment.MachineName); SubjectLocalityType subjectLocality = new SubjectLocalityType(); subjectLocality.IPAddress = ipEntry.AddressList[0].ToString(); authStatement.SubjectLocality = subjectLocality; attrStatement.Attribute = new AttributeType[attributes.Count]; int i = 0; // Create userName SAML attributes. foreach (KeyValuePair <string, string> attribute in attributes) { AttributeType attr = new AttributeType(); attr.AttributeName = attribute.Key; attr.AttributeNamespace = domain; attr.AttributeValue = new object[] { attribute.Value }; attrStatement.Attribute[i] = attr; i++; } assertion.Conditions = conditions; assertion.Items = new StatementAbstractType[] { authStatement, attrStatement }; return(assertion); }
/// <summary> /// Creates a SAML 2.0 Assertion Segment for a Response /// Simple implmenetation assuming a list of string key and value pairs /// </summary> /// <param name="Issuer"></param> /// <param name="AssertionExpirationMinutes"></param> /// <param name="Audience"></param> /// <param name="Subject"></param> /// <param name="Recipient"></param> /// <param name="Attributes">Dictionary of string key, string value pairs</param> /// <returns>Assertion to sign and include in Response</returns> private static AssertionType CreateSAML20Assertion(string Issuer, int AssertionExpirationMinutes, string Audience, string Subject, string Recipient, Dictionary <string, string> Attributes) { AssertionType NewAssertion = new AssertionType() { Version = "2.0", IssueInstant = DateTime.Now,//DateTime.UtcNow, ID = "_" + System.Guid.NewGuid().ToString() }; // Create Issuer NewAssertion.Issuer = new NameIDType() { Value = Issuer.Trim() }; // Create Assertion Subject SubjectType subject = new SubjectType(); NameIDType subjectNameIdentifier = new NameIDType() { Value = Subject.Trim(), Format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" }; SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType() { Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer", SubjectConfirmationData = new SubjectConfirmationDataType() { NotOnOrAfter = DateTime.Now.AddMinutes(AssertionExpirationMinutes), Recipient = Recipient } }; //{ NotOnOrAfter = DateTime.UtcNow.AddMinutes(AssertionExpirationMinutes), Recipient = Recipient } }; subject.Items = new object[] { subjectNameIdentifier, subjectConfirmation }; NewAssertion.Subject = subject; // Create Assertion Conditions ConditionsType conditions = new ConditionsType(); conditions.NotBefore = DateTime.Now; //DateTime.UtcNow; conditions.NotBeforeSpecified = true; conditions.NotOnOrAfter = DateTime.Now.AddMinutes(AssertionExpirationMinutes); //DateTime.UtcNow.AddMinutes(AssertionExpirationMinutes); conditions.NotOnOrAfterSpecified = true; conditions.Items = new ConditionAbstractType[] { new AudienceRestrictionType() { Audience = new string[] { Audience.Trim() } } }; NewAssertion.Conditions = conditions; // Add AuthnStatement and Attributes as Items AuthnStatementType authStatement = new AuthnStatementType() { AuthnInstant = DateTime.Now, SessionIndex = NewAssertion.ID }; //{ AuthnInstant = DateTime.UtcNow, SessionIndex = NewAssertion.ID }; AuthnContextType context = new AuthnContextType(); context.ItemsElementName = new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef }; context.Items = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" }; authStatement.AuthnContext = context; AttributeStatementType attributeStatement = new AttributeStatementType(); attributeStatement.Items = new AttributeType[Attributes.Count]; int i = 0; foreach (KeyValuePair <string, string> attribute in Attributes) { attributeStatement.Items[i] = new AttributeType() { Name = attribute.Key, AttributeValue = new object[] { attribute.Value }, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic" }; i++; } NewAssertion.Items = new StatementAbstractType[] { authStatement, attributeStatement }; return(NewAssertion); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> private XmlDocument GenerateResponseMetadata(SAMLContext context, string id) { DateTime now = DateTime.UtcNow; MemoryStream stream = new MemoryStream(); StreamReader reader; XmlTextReader xmlReader; ResponseType response = new ResponseType(); response.ID = id; response.InResponseTo = context.RequestID; response.Version = SAMLConstants.SAML_VERSION; response.IssueInstant = now; response.Destination = context.AssertionConsumer; response.Consent = SAMLConstants.CONSENT; response.Issuer = new NameIDType(); response.Issuer.Value = thisIssuer; response.Issuer.Format = SAMLConstants.ThisIssuerFormat; response.Status = new StatusType(); response.Status.StatusCode = new StatusCodeType(); response.Status.StatusCode.Value = SAMLConstants.StatusCode.statusCode[context.StatusCode]; if (context.StatusCode != SAMLConstants.StatusCode.SUCCESS) { response.Status.StatusCode.StatusCode = new StatusCodeType(); response.Status.StatusCode.StatusCode.Value = SAMLConstants.StatusCode.statusCode[context.SubStatusCode]; response.Status.StatusMessage = context.StatusMessage; } AssertionType assertion = new AssertionType(); assertion.ID = "_" + Guid.NewGuid().ToString(); assertion.Version = SAMLConstants.SAML_VERSION; assertion.IssueInstant = now; assertion.Issuer = new NameIDType(); assertion.Issuer.Value = thisIssuer; assertion.Issuer.Format = SAMLConstants.ThisIssuerFormat; assertion.Subject = new SubjectType(); NameIDType nameId = new NameIDType(); nameId.Format = "urn:oasis:names:tc:SAML:1.1:nameid- format:unspecified"; //nameId.NameQualifier = "http://C-PEPS.gov.xx"; nameId.Value = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"; SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType(); subjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer"; subjectConfirmation.SubjectConfirmationData = new SubjectConfirmationDataType(); subjectConfirmation.SubjectConfirmationData.Address = context.SubjectAddress; subjectConfirmation.SubjectConfirmationData.InResponseTo = context.RequestID; //subjectConfirmation.SubjectConfirmationData.NotBeforeString = "2010-02-03T17:06:18.099Z"; subjectConfirmation.SubjectConfirmationData.NotOnOrAfterString = String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now.AddMinutes(validTimeframe)); subjectConfirmation.SubjectConfirmationData.Recipient = context.Issuer; assertion.Subject.Items = new object[] { nameId, subjectConfirmation }; assertion.Conditions = new ConditionsType(); assertion.Conditions.NotBeforeString = String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now); assertion.Conditions.NotOnOrAfterString = String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now.AddMinutes(validTimeframe)); AudienceRestrictionType audience = new AudienceRestrictionType(); audience.Audience = new string[] { context.Issuer }; // FIXME assertion.Conditions.Items = new ConditionAbstractType[] { audience, new OneTimeUseType() }; AuthnStatementType authnStatement = new AuthnStatementType(); authnStatement.AuthnInstant = now; authnStatement.AuthnContext = new AuthnContextType(); List <AttributeElement> attributes = context.GetAttributes(); object[] attributesDescription = new AttributeType[attributes.Count]; AttributeType attr; XmlAttribute statusAttr; int i = 0; foreach (AttributeElement element in attributes) { attr = new AttributeType(); attr.Name = element.AttrName; attr.NameFormat = element.NameFormat; if (context.StatusCode == SAMLConstants.StatusCode.SUCCESS) { if (element.AttrStatus == SAMLConstants.AttributeStatus.AVAILABLE && element.AttrValue != null) { attr.AttributeValue = new object[] { element.AttrValue } } ; if (element.AttrStatus >= 0) { statusAttr = new XmlDocument(). CreateAttribute(SAMLConstants.ATTRIBUTE_STATUS_STR, SAMLConstants.NS_STORK_ASSER); statusAttr.Value = element.Status; attr.AnyAttr = new XmlAttribute[] { statusAttr }; } } attributesDescription[i++] = attr; } AttributeStatementType attributeStatement = new AttributeStatementType(); attributeStatement.Items = attributesDescription; assertion.Items = new StatementAbstractType[] { authnStatement, attributeStatement }; response.Items = new object[] { assertion }; stream = new MemoryStream(); Serialize(response, stream); reader = new StreamReader(stream); stream.Seek(0, SeekOrigin.Begin); xmlReader = new XmlTextReader(new StringReader(reader.ReadToEnd())); return(Deserialize <XmlDocument>(xmlReader)); }
private SAMLResponse ExtractResponseValues(XmlDocument doc) { _logger.Trace("Start;"); SAMLResponse context = new SAMLResponse(SAMLConstants.ErrorCodes.VALID); XmlReader reader = new XmlTextReader(new StringReader(doc.OuterXml)); ResponseType response = Deserialize <ResponseType>(reader); context.InResponseTo = response.InResponseTo; context.Idp = response.Issuer.Value; int statusCode = SAMLConstants.StatusCode.GetStatusCodeFromDesc(response.Status.StatusCode.Value); if (statusCode < 0 && response.Status.StatusCode.StatusCode != null) { context.StatusCode = SAMLConstants.StatusCode.GetStatusCodeFromDesc(response.Status.StatusCode.StatusCode.Value); } else { context.StatusCode = statusCode; } if (Math.Abs(response.IssueInstant.Subtract(DateTime.UtcNow).TotalMinutes) > validTimeframe) { context.ErrorCode = SAMLConstants.ErrorCodes.EXPIRED; return(context); } if (statusCode != SAMLConstants.StatusCode.SUCCESS) { int subStatusCode = SAMLConstants.StatusCode.GetStatusCodeFromDesc(response.Status.StatusCode.StatusCode.Value); if (subStatusCode != -1) { context.SubStatusCode = subStatusCode; context.StatusMessage = response.Status.StatusMessage; } return(context); } int i; for (i = 0; i < response.Items.Length; i++) { if (response.Items[i].GetType() == typeof(AssertionType)) { break; } } AssertionType assertion = (AssertionType)response.Items[i]; DateTime now = DateTime.UtcNow; TimeSpan tSpan = new TimeSpan(0, 0, skewClock); if (now < assertion.Conditions.NotBefore.Subtract(tSpan) || now >= assertion.Conditions.NotOnOrAfter.Add(tSpan)) { context.ErrorCode = SAMLConstants.ErrorCodes.EXPIRED_ASSERTION; return(context); } for (i = 0; i < assertion.Items.Length; i++) { if (assertion.Items[i].GetType() == typeof(AttributeStatementType)) { break; } } AttributeStatementType attrStatement = (AttributeStatementType)assertion.Items[i]; foreach (object o in attrStatement.Items) { AttributeType attr = (AttributeType)o; if (!citizenAttributes.Exists(attr.Name)) { context.ErrorCode = SAMLConstants.ErrorCodes.INVALID_ATTRIBUTES; return(context); } int attrStatus = SAMLConstants.AttributeStatus.AVAILABLE; if (attr.AnyAttr != null) { for (i = 0; i < attr.AnyAttr.Length; i++) { if (attr.AnyAttr[i].LocalName == SAMLConstants.ATTRIBUTE_STATUS_STR) { attrStatus = SAMLConstants.AttributeStatus.GetAttrStatusFromDesc(attr.AnyAttr[i].Value); break; } } } string attrValue = null; if (attr.AttributeValue != null && attr.AttributeValue.Length > 0) { if (attr.AttributeValue[0] is System.Xml.XmlNode[]) { System.Xml.XmlNode[] nodeValues = ((System.Xml.XmlNode[])attr.AttributeValue[0]); int size = nodeValues.Length; Dictionary <string, string> values = new Dictionary <string, string>(size); for (int j = 0; j < size; j++) { if (nodeValues[j].NodeType.Equals(System.Xml.XmlNodeType.Text)) { values.Add((string)nodeValues[j].LocalName, (string)nodeValues[j].InnerText); } } context.AddAttribute(attr.Name, values, attrStatus); } else { attrValue = (string)attr.AttributeValue[0]; context.AddAttribute(attr.Name, attrValue, attrStatus); } } else { context.AddAttribute(attr.Name, attrValue, attrStatus); } } if (context.GetAttributeNames().Count == 0) { context.ErrorCode = SAMLConstants.ErrorCodes.INVALID_ATTRIBUTES; } _logger.Trace("SAMLResponse {0}, {1}, {2}", context.StatusCode, context.StatusMessage, context.ErrorCode); _logger.Trace("SAMLResponse {0}, {1}", context.GetAttributeNames().Count, context.StatusMessage); return(context); }
public void processResponse(XmlDocument xml, HttpContext context, XmlReader reader, string relayState) { string nic = string.Empty, nomeCompleto = string.Empty; // desserializar xml para ResponseType XmlSerializer serializer = new XmlSerializer(typeof(ResponseType)); ResponseType response = (ResponseType)serializer.Deserialize(reader); // verificar validade temporal: int validTimeFrame = 5; if (Math.Abs(response.IssueInstant.Subtract(DateTime.UtcNow).TotalMinutes) > validTimeFrame) { throw new Exception("SAML Response fora do intervalo de validade - validade da resposta: " + response.IssueInstant); } relayState = System.Text.UTF8Encoding.UTF8.GetString(System.Convert.FromBase64String(relayState)); if ("urn:oasis:names:tc:SAML:2.0:status:Success".Equals(response.Status.StatusCode.Value)) { AssertionType assertion = new AssertionType(); for (int i = 0; i < response.Items.Length; i++) { if (response.Items[i].GetType() == typeof(AssertionType)) { assertion = (AssertionType)response.Items[i]; break; } } // validade da asserção: DateTime now = DateTime.UtcNow; TimeSpan tSpan = new TimeSpan(0, 0, 150); // 2,5 minutos if (now < assertion.Conditions.NotBefore.Subtract(tSpan) || now >= assertion.Conditions.NotOnOrAfter.Add(tSpan)) { // Asserção inválida // TODO: redireccionar para página de erro/login throw new Exception("Asserções temporalmente inválidas."); } AttributeStatementType attrStatement = new AttributeStatementType(); for (int i = 0; i < assertion.Items.Length; i++) { if (assertion.Items[i].GetType() == typeof(AttributeStatementType)) { attrStatement = (AttributeStatementType)assertion.Items[i]; break; } } foreach (object obj in attrStatement.Items) { AttributeType attr = (AttributeType)obj; if (attr.AnyAttr != null) { for (int i = 0; i < attr.AnyAttr.Length; i++) { XmlAttribute xa = attr.AnyAttr[i]; if (xa.LocalName.Equals("AttributeStatus") && xa.Value.Equals("Available")) { if (attr.AttributeValue != null && attr.AttributeValue.Length > 0) { if (((string)attr.Name).Equals("http://interop.gov.pt/MDC/Cidadao/NIC")) { nic = (string)attr.AttributeValue[0]; } } //else if (((string)attr.Name).Equals("http://interop.gov.pt/MDC/Cidadao/NomeCompleto")) // nomeCompleto = (string)attr.AttributeValue[0]; } } } } MembershipUser _user = Membership.GetUser(nic); // Verificar se utilizador existe if (_user != null) { // Se existe, registar login... FormsAuthentication.SetAuthCookie(nic, false /* createPersistentCookie */); // ...e redireccionar para página recebida no relayState if (!string.IsNullOrEmpty(relayState)) { relayState = relayState.Substring(relayState.IndexOf("=") + 1); context.Response.Redirect(VirtualPathUtility.ToAbsolute(relayState)); } else { context.Response.Redirect(VirtualPathUtility.ToAbsolute("~/Default.aspx")); // Ocorreu erro? } } else { // Se não existe, enviar o utilizador para a página de registo // passar informação para a página que utilizará os dados obtidos: context.Session.Add("Nic", nic); context.Session.Add("RelayState", relayState); context.Response.Redirect("~/Account/Register.aspx"); context.Response.End(); } } else { //Caso o retorno não seja sucesso, definir qual dever ser context.Response.Redirect("~/Account/Login.aspx"); context.Response.End(); } }
public SamlUser Map(ResponseType response) { SamlUser user = new SamlUser(); AssertionType assertion = response.Items.OfType <AssertionType>().FirstOrDefault(); if (assertion != null) { AttributeStatementType attributeStatement = assertion.Items.OfType <AttributeStatementType>().FirstOrDefault(); if (attributeStatement != null) { foreach (AttributeType attribute in attributeStatement.Items.OfType <AttributeType>()) { switch (attribute.Name) { case "spidCode": user.SpidCode = attribute.AttributeValue[0].ToString(); break; case "name": user.Name = attribute.AttributeValue[0].ToString(); break; case "familyName": user.Surname = attribute.AttributeValue[0].ToString(); break; case "gender": user.Gender = attribute.AttributeValue[0].ToString(); break; case "ivaCode": user.IvaCode = attribute.AttributeValue[0].ToString().Replace("VATIT-", string.Empty); break; case "companyName": user.CompanyName = attribute.AttributeValue[0].ToString(); break; case "mobilePhone": user.MobilePhone = attribute.AttributeValue[0].ToString(); break; case "address": user.Address = attribute.AttributeValue[0].ToString(); break; case "fiscalNumber": user.FiscalNumber = attribute.AttributeValue[0].ToString().Replace("TINIT-", string.Empty); break; case "dateOfBirth": user.DateOfBirth = attribute.AttributeValue[0].ToString(); break; case "countyOfBirth": user.CountyOfBirth = attribute.AttributeValue[0].ToString(); break; case "placeOfBirth": user.PlaceOfBirth = attribute.AttributeValue[0].ToString(); break; case "idCard": user.IdCard = attribute.AttributeValue[0].ToString(); break; case "registeredOffice": user.RegisteredOffice = attribute.AttributeValue[0].ToString(); break; case "email": user.Email = attribute.AttributeValue[0].ToString(); break; case "expirationDate": user.ExpirationDate = attribute.AttributeValue[0].ToString(); break; case "digitalAddress": user.DigitalAddress = attribute.AttributeValue[0].ToString(); break; default: break; } } } } return(user); }
/// <REMARKS> /// AuthenticateSAMLResponse supports SP-Initiated and IDP-Initated, POST /// Does not pass specific SAML status values back to the caller; caller sends SAML Failed or Success status /// </REMARKS> internal static bool AuthenticateSamlResponse() { //Authenticated SAML Response will have the SAML token, transform the token into PTS Credential, create the principal, authenticated=true, create the SP cookie string parameterSamlResponse = HttpContext.Current.Request.Form[Helpers.Names.HttpParameterResponseSaml]; if (string.IsNullOrEmpty(parameterSamlResponse)) { return(HttpContext.Current.Request.IsAuthenticated); } //Validate SAML Response string decodedSamlResponse = Helpers.Helper.Utf8Base64DecodeString(parameterSamlResponse); XmlDocument xmlResponse = Helpers.Helper.ReadyXmlDocument; xmlResponse.LoadXml(decodedSamlResponse); ResponseType response = Helpers.Helper.DeserializeXmlDocumentToType <ResponseType>(xmlResponse); XmlElement xmlSignature = Saml.Helper.SelectXMLElement(xmlResponse, Names.SAMLNamesElementAssertionSignature, SignedXml.XmlDsigNamespaceUrl); //SAML Response objects are Federated; if the response is verified then the subject is trusted (authenticated) //However, from Federated IDPs the assertions must match the PTS Endpoint Claim set registered in SQL if (xmlSignature == null || !Saml.Helper.VerifySignedXMLElement(xmlResponse.DocumentElement, xmlSignature)) { return(HttpContext.Current.Request.IsAuthenticated); } //From SAML Response assertions and RelayState, validate the user and build the PTS authenticated credential AssertionType assertion = response.Items.Where(t => t.GetType().FullName == typeof(AssertionType).FullName)?.First() as AssertionType; NameIDType nameId = assertion.Subject.Items.Where(t => t.GetType().FullName == typeof(NameIDType).FullName)?.First() as NameIDType; AttributeStatementType statement = assertion?.Items.Where(t => t.GetType().FullName == typeof(AttributeStatementType).FullName)?.First() as AttributeStatementType; List <AttributeType> attributeList = statement?.Items.Select(a => (AttributeType)a)?.ToList(); string subjectNameId = nameId?.Value; //Response message not expired; eliminates replay attack if (DateTime.Now >= assertion.Conditions.NotOnOrAfter) { return(HttpContext.Current.Request.IsAuthenticated); } Credential credential = new Credential { EntityId = subjectNameId, ClaimsId = assertion.Issuer.Value, Refresh = true }; //Claim set valid; eliminate man-in-the-middle attack if (!AuthenticateSamlAssertion(attributeList, ref credential)) { return(HttpContext.Current.Request.IsAuthenticated); } XmlDocument xmlCredential = Helpers.Helper.SerializeTypeToXmlDocument(credential); //Deflate (W3C) and Encrypt (RSA) the PTS SSO XML Document credential... string credentialDeflatedEncrypted = Helpers.Helper.XmlDocumentDeflateEncrypt(xmlCredential); //Create Authenticated Principal from PTS Credential ClaimsIdentity claimsIdentity = new ClaimsIdentity( new GenericIdentity(credential.Email, Helpers.Names.PrincipalType), credential.Claims.Select(c => new System.Security.Claims.Claim($"{c.Name}:{c.FriendlyName}", c.Value, c.NameFormat, c.EntityId)) //Inserting a Generic Identity into the Claims Identity makes the User context both claim and role aware... ); HttpContext.Current.User = new GenericPrincipal(claimsIdentity, credential.Roles.Select(r => r.Name).ToArray()); //Set PTS Authentication Session cookie; note the IIS Pipeline cache is not available in the application authenticaiton event //The only other cache choice for user credentials is another call to SQL Server with each IIS Pipeline request HttpContext.Current.Response.Cookies.Add(new HttpCookie(Helpers.Names.HttpCookiePtsSso) { //IDP root session cookie, not persistant, not client script accessible, value is segmented, encrypted and defalted (W3C/RSA compliant) Expires = DateTime.MinValue, HttpOnly = true, Path = Helpers.Names.PathRoot, Value = credentialDeflatedEncrypted }); return(HttpContext.Current.Request.IsAuthenticated); }
public void Deserialize(string samlResponse) { ResponseType response = new ResponseType(); try { using (TextReader sr = new StringReader(samlResponse)) { var serializer = new System.Xml.Serialization.XmlSerializer(typeof(ResponseType)); response = (ResponseType)serializer.Deserialize(sr); this.Version = response.Version; this.UUID = response.ID; this.SPUID = response.InResponseTo; this.Issuer = response.Issuer.Value; switch (response.Status.StatusCode.Value) { case "urn:oasis:names:tc:SAML:2.0:status:Success": this.RequestStatus = SamlRequestStatus.Success; break; case "urn:oasis:names:tc:SAML:2.0:status:Requester": this.RequestStatus = SamlRequestStatus.RequesterError; break; case "urn:oasis:names:tc:SAML:2.0:status:Responder": this.RequestStatus = SamlRequestStatus.ResponderError; break; case "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch": this.RequestStatus = SamlRequestStatus.VersionMismatchError; break; case "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed": this.RequestStatus = SamlRequestStatus.AuthnFailed; break; case "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue": this.RequestStatus = SamlRequestStatus.InvalidAttrNameOrValue; break; case "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy": this.RequestStatus = SamlRequestStatus.InvalidNameIDPolicy; break; case "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext": this.RequestStatus = SamlRequestStatus.NoAuthnContext; break; case "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP": this.RequestStatus = SamlRequestStatus.NoAvailableIDP; break; case "urn:oasis:names:tc:SAML:2.0:status:NoPassive": this.RequestStatus = SamlRequestStatus.NoPassive; break; case "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP": this.RequestStatus = SamlRequestStatus.NoSupportedIDP; break; case "urn:oasis:names:tc:SAML:2.0:status:PartialLogout": this.RequestStatus = SamlRequestStatus.PartialLogout; break; case "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded": this.RequestStatus = SamlRequestStatus.ProxyCountExceeded; break; case "urn:oasis:names:tc:SAML:2.0:status:RequestDenied": this.RequestStatus = SamlRequestStatus.RequestDenied; break; case "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported": this.RequestStatus = SamlRequestStatus.RequestUnsupported; break; case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated": this.RequestStatus = SamlRequestStatus.RequestVersionDeprecated; break; case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh": this.RequestStatus = SamlRequestStatus.RequestVersionTooHigh; break; case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow": this.RequestStatus = SamlRequestStatus.RequestVersionTooLow; break; case "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized": this.RequestStatus = SamlRequestStatus.ResourceNotRecognized; break; case "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses": this.RequestStatus = SamlRequestStatus.TooManyResponses; break; case "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile": this.RequestStatus = SamlRequestStatus.UnknownAttrProfile; break; case "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal": this.RequestStatus = SamlRequestStatus.UnknownPrincipal; break; case "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding": this.RequestStatus = SamlRequestStatus.UnsupportedBinding; break; default: this.RequestStatus = SamlRequestStatus.GenericError; break; } if (this.RequestStatus == SamlRequestStatus.Success) { foreach (var item in response.Items) { if (item.GetType() == typeof(AssertionType)) { AssertionType ass = (AssertionType)item; this.SessionIdExpireDate = (ass.Conditions.NotOnOrAfter != null) ? ass.Conditions.NotOnOrAfter : DateTime.Now.AddMinutes(20); foreach (var subitem in ass.Subject.Items) { if (subitem.GetType() == typeof(NameIDType)) { NameIDType nameId = (NameIDType)subitem; this.SubjectNameId = nameId.Value; //.Replace("SPID-",""); } } foreach (var assItem in ass.Items) { if (assItem.GetType() == typeof(AuthnStatementType)) { AuthnStatementType authnStatement = (AuthnStatementType)assItem; this.SessionId = authnStatement.SessionIndex; this.SessionIdExpireDate = (authnStatement.SessionNotOnOrAfterSpecified) ? authnStatement.SessionNotOnOrAfter : this.SessionIdExpireDate; } if (assItem.GetType() == typeof(AttributeStatementType)) { AttributeStatementType statement = (AttributeStatementType)assItem; foreach (AttributeType attribute in statement.Items) { switch (attribute.Name) { case "spidCode": this.User.SpidCode = attribute.AttributeValue[0].ToString(); break; case "name": this.User.Name = attribute.AttributeValue[0].ToString(); break; case "familyName": this.User.FamilyName = attribute.AttributeValue[0].ToString(); break; case "gender": this.User.Gender = attribute.AttributeValue[0].ToString(); break; case "ivaCode": this.User.IvaCode = attribute.AttributeValue[0].ToString(); break; case "companyName": this.User.CompanyName = attribute.AttributeValue[0].ToString(); break; case "mobilePhone": this.User.MobilePhone = attribute.AttributeValue[0].ToString(); break; case "address": this.User.Address = attribute.AttributeValue[0].ToString(); break; case "fiscalNumber": this.User.FiscalNumber = attribute.AttributeValue[0].ToString(); break; case "dateOfBirth": this.User.DateOfBirth = attribute.AttributeValue[0].ToString(); break; case "placeOfBirth": this.User.PlaceOfBirth = attribute.AttributeValue[0].ToString(); break; case "countyOfBirth": this.User.CountyOfBirth = attribute.AttributeValue[0].ToString(); break; case "idCard": this.User.IdCard = attribute.AttributeValue[0].ToString(); break; case "registeredOffice": this.User.RegisteredOffice = attribute.AttributeValue[0].ToString(); break; case "email": this.User.Email = attribute.AttributeValue[0].ToString(); break; case "expirationDate": this.User.ExpirationDate = attribute.AttributeValue[0].ToString(); break; case "digitalAddress": this.User.DigitalAddress = attribute.AttributeValue[0].ToString(); break; default: break; } } } } } } } } } catch (Exception ex) { //TODO Log throw ex; } }
/// <summary> /// Creates a SAML 2.0 Assertion Segment for a Response /// Simple implmenetation assuming a list of string key and value pairs /// </summary> /// <param name="issuer"></param> /// <param name="assertionExpirationMinutes"></param> /// <param name="audience"></param> /// <param name="subject"></param> /// <param name="recipient"></param> /// <param name="attributes">Dictionary of string key, string value pairs</param> /// <returns>Assertion to sign and include in Response</returns> private static AssertionType CreateSaml20Assertion(string issuer, int assertionExpirationMinutes, string audience, string subject, string recipient, Dictionary <string, string> attributes) { AssertionType newAssertion = new AssertionType { Version = "2.0", IssueInstant = DateTime.UtcNow, ID = "_" + Guid.NewGuid(), Issuer = new NameIDType { Value = issuer.Trim() } }; // Create Issuer // Create Assertion Subject SubjectType subjectType = new SubjectType(); NameIDType subjectNameIdentifier = new NameIDType { Value = subject.Trim(), Format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" }; SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType { Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer", SubjectConfirmationData = new SubjectConfirmationDataType { NotOnOrAfter = DateTime.UtcNow.AddMinutes(assertionExpirationMinutes), Recipient = recipient } }; subjectType.Items = new object[] { subjectNameIdentifier, subjectConfirmation }; newAssertion.Subject = subjectType; // Create Assertion Conditions ConditionsType conditions = new ConditionsType { NotBefore = DateTime.UtcNow, NotBeforeSpecified = true, NotOnOrAfter = DateTime.UtcNow.AddMinutes(assertionExpirationMinutes), NotOnOrAfterSpecified = true, Items = new ConditionAbstractType[] { new AudienceRestrictionType { Audience = new[] { audience.Trim() } } } }; newAssertion.Conditions = conditions; // Add AuthnStatement and Attributes as Items AuthnStatementType authStatement = new AuthnStatementType { AuthnInstant = DateTime.UtcNow, SessionIndex = newAssertion.ID }; AuthnContextType context = new AuthnContextType { ItemsElementName = new[] { ItemsChoiceType5.AuthnContextClassRef }, Items = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" } }; authStatement.AuthnContext = context; AttributeStatementType attributeStatement = new AttributeStatementType { Items = new object[attributes.Count] }; int i = 0; foreach (KeyValuePair <string, string> attribute in attributes) { attributeStatement.Items[i] = new AttributeType { Name = attribute.Key, AttributeValue = new object[] { attribute.Value }, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic" }; i++; } newAssertion.Items = new StatementAbstractType[] { authStatement, attributeStatement }; return(newAssertion); }
/// <summary> /// Creates a Version 1.1 Saml Assertion /// </summary> /// <param name="issuer">Issuer</param> /// <param name="subject">Subject</param> /// <param name="attributes">Attributes</param> /// <returns>returns a Version 1.1 Saml Assertion</returns> private static AssertionType CreateSamlAssertion(string issuer, string recipient, string domain, string subject, Dictionary <string, string> attributes) { // Here we create some SAML assertion with ID and Issuer name. AssertionType assertion = new AssertionType(); assertion.ID = "_" + Guid.NewGuid().ToString(); NameIDType issuerForAssertion = new NameIDType(); issuerForAssertion.Value = issuer.Trim(); assertion.Issuer = issuerForAssertion; assertion.Version = "2.0"; assertion.IssueInstant = System.DateTime.UtcNow; //Not before, not after conditions ConditionsType conditions = new ConditionsType(); conditions.NotBefore = DateTime.UtcNow; conditions.NotBeforeSpecified = true; conditions.NotOnOrAfter = DateTime.UtcNow.AddMinutes(5); conditions.NotOnOrAfterSpecified = true; AudienceRestrictionType audienceRestriction = new AudienceRestrictionType(); audienceRestriction.Audience = new string[] { domain.Trim() }; conditions.Items = new ConditionAbstractType[] { audienceRestriction }; //Name Identifier to be used in Saml Subject NameIDType nameIdentifier = new NameIDType(); nameIdentifier.NameQualifier = domain.Trim(); nameIdentifier.Value = subject.Trim(); SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType(); SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType(); subjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer"; subjectConfirmation.SubjectConfirmationData = subjectConfirmationData; // // Create some SAML subject. SubjectType samlSubject = new SubjectType(); AttributeStatementType attrStatement = new AttributeStatementType(); AuthnStatementType authStatement = new AuthnStatementType(); authStatement.AuthnInstant = DateTime.UtcNow; AuthnContextType context = new AuthnContextType(); context.ItemsElementName = new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef }; context.Items = new object[] { "AuthnContextClassRef" }; authStatement.AuthnContext = context; samlSubject.Items = new object[] { nameIdentifier, subjectConfirmation }; assertion.Subject = samlSubject; IPHostEntry ipEntry = Dns.GetHostEntry(System.Environment.MachineName); SubjectLocalityType subjectLocality = new SubjectLocalityType(); subjectLocality.Address = ipEntry.AddressList[0].ToString(); attrStatement.Items = new AttributeType[attributes.Count]; int i = 0; // Create userName SAML attributes. foreach (KeyValuePair <string, string> attribute in attributes) { AttributeType attr = new AttributeType(); attr.Name = attribute.Key; attr.NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"; attr.AttributeValue = new object[] { attribute.Value }; attrStatement.Items[i] = attr; i++; } assertion.Conditions = conditions; assertion.Items = new StatementAbstractType[] { authStatement, attrStatement }; return(assertion); }
public static IEnumerable <AttributeType> GetAttributes(this AttributeStatementType input) => input.Items?.Cast <AttributeType>();