Thursday, June 17, 2021

EPiServer - Get Content Area Items.

Visual Studio / Resharper - Key Board Shortcuts

  • Add New File: CTRL + SHIFT + A
  • GOTO Solution Explorer:  CTRL + ALT + L



Fix problems:
 Disable Resharper temp.
Then go to keyboard press reset!
Reactivate resharper and set vs key bindings.



Fix Resharper fucked up " Add new item in Solution Explorer " Shortcut.


Friday, June 4, 2021

EPiServer Search - Not starting

Add this to web.config handlers.

 <remove name="svc-Integrated-4.0" />


  <add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />



Remove anything that can interfere with 404.<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace">

      <remove statusCode="404" />

      <error statusCode="404" path="/404" responseMode="ExecuteURL" />

    </httpErrors>



Good guide 

https://world.episerver.com/documentation/developer-guides/CMS/search/full-text-search-legacy/Installing-and-deploying-Search-Service/

https://sveinaandahl.blogspot.com/2013/06/how-to-install-episerver-search-for.html


Good tool

https://gregwiechec.com/2015/09/episerver-search-diagnostic-tool/

Thursday, June 3, 2021

C# - SAML Example

using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;

namespace UI.Business.SAML
{
    public class SamlService
    {
        private XmlDocument _samlXmlDocument;
        private XmlNamespaceManager _manager;

        public void LoadXml(string xml)
        {
            _samlXmlDocument = new XmlDocument {PreserveWhitespace = true, XmlResolver = null};
            _samlXmlDocument.LoadXml(xml);

            LoadNamespaceManager();
        }

        public void LoadXmlFromBase64(string response)
        {
            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
            LoadXml(enc.GetString(Convert.FromBase64String(response)));
        }

        private void LoadNamespaceManager()
        {
            _manager = new XmlNamespaceManager(_samlXmlDocument.NameTable);
            _manager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
            _manager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
            _manager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
        }

        public bool IsValid()
        {
            bool status = false;

            // The date is skew to allow the idp clock and this server click to be abit out of sync without failing the validation.
            var skewDateForValidation = DateTime.Now.AddSeconds(20);

            XmlNodeList nodeList = _samlXmlDocument.SelectNodes("//ds:Signature", _manager);
            if (nodeList != null)
            {
                status = true;
                SignedXml signedXml = new SignedXml(_samlXmlDocument);
                signedXml.LoadXml((XmlElement) nodeList[0]);

                status &= signedXml.CheckSignature(GetCertificate(), true);

                var notBefore = NotBefore();
                status &= !notBefore.HasValue || (notBefore <= skewDateForValidation);

                var notOnOrAfter = NotOnOrAfter();
                status &= !notOnOrAfter.HasValue || (notOnOrAfter > skewDateForValidation);
            }

            return status;
        }

        public X509Certificate2 GetCertificate()
        {
            using (var store = new X509Store(StoreLocation.LocalMachine))
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByIssuerDistinguishedName,
                    "L=Sachsen, CN=www.staffbase.com, O=Staffbase GmbH, C=DE", false);

                return certs.Count > 0 ? certs[0] : null;
            }
        }


        public DateTime? NotBefore()
        {
            var nodes = _samlXmlDocument.SelectNodes("/samlp:Response/saml:Assertion/saml:Conditions", _manager);
            string value = null;
            if (nodes != null && nodes.Count > 0 && nodes[0]?.Attributes?["NotBefore"] != null)
            {
                value = nodes[0].Attributes["NotBefore"].Value;
            }

            return value != null ? DateTime.Parse(value) : (DateTime?) null;
        }

        public DateTime? NotOnOrAfter()
        {
            var nodes = _samlXmlDocument.SelectNodes("/samlp:Response/saml:Assertion/saml:Conditions", _manager);
            string value = null;
            if (nodes != null && nodes.Count > 0 && nodes[0]?.Attributes?["NotOnOrAfter"] != null)
            {
                value = nodes[0].Attributes["NotOnOrAfter"].Value;
            }

            return value != null ? DateTime.Parse(value) : (DateTime?) null;
        }

        public List<Claim> GetStaffbaseClaims()
        {
            var claimsNs = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/";
            var nameId = GetCustomAttribute(claimsNs + "nameidentifier");
            var givenName = GetCustomAttribute(claimsNs + "givenname");
            var surName = GetCustomAttribute(claimsNs + "surname");
            var workplaceCode = GetCustomAttribute("arbetsplatskod");
            var occupationCode = GetCustomAttribute("yrkeskod");
            var employeeNumber = GetCustomAttribute("employeeNumber");

            var claims = new List<Claim>();
            if (!string.IsNullOrWhiteSpace(givenName) || !string.IsNullOrWhiteSpace(surName))
                claims.Add(new Claim(ClaimTypes.Name, $"{givenName} {surName}"));
            if (!string.IsNullOrWhiteSpace(nameId))
                claims.Add(new Claim(ClaimTypes.NameIdentifier, nameId));

            // Used as a validation that the user we get in claims is an AD user. If not we do not give it the role "Intranet user"
            if (!string.IsNullOrWhiteSpace(employeeNumber))
                claims.Add(new Claim(ClaimTypes.WindowsAccountName, employeeNumber));
            // Set to workplace code is set to Upn claim because the rest of the site depends on it there
            if (!string.IsNullOrWhiteSpace(workplaceCode))
                claims.Add(new Claim(ClaimTypes.Upn, workplaceCode));
            // Set to occupationcode code is set to surname claim because the rest of the site depends on it there
            if (!string.IsNullOrWhiteSpace(occupationCode))
                claims.Add(new Claim(ClaimTypes.Surname, occupationCode));

            return claims;
        }
        public string GetCustomAttribute(string attr)
        {
            XmlNode node = _samlXmlDocument.SelectSingleNode("/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name='" + attr + "']/saml:AttributeValue", _manager);
            return node?.InnerText;
        }

        public string GetNameId()
        {
            XmlNode node = _samlXmlDocument.SelectSingleNode("/samlp:Response/saml:Assertion/saml:Subject/saml:NameID", _manager);
            return node?.InnerText;
        }
    }
}