Ejemplo n.º 1
0
        protected static bool ValidateKombitAttributeProfile(Saml20Identity current)
        {
            if (current == null)
            {
                throw new ArgumentNullException("current");
            }
            if (!current.HasAttribute("dk:gov:saml:attribute:AssuranceLevel"))
            {
                return(false);
            }
            if (!current.HasAttribute("dk:gov:saml:attribute:SpecVer"))
            {
                return(false);
            }
            if (!current.HasAttribute("dk:gov:saml:attribute:KombitSpecVer"))
            {
                return(false);
            }
            if (!current.HasAttribute("dk:gov:saml:attribute:CvrNumberIdentifier"))
            {
                return(false);
            }
            if (!current.HasAttribute("dk:gov:saml:attribute:Privileges_intermediate"))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Extracts the Basic privilege profile (simple or intermediate) from the saml attributes
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        public static IEnumerable <Privilege> GetBasicPrivilegeProfilePrivileges(Saml20Identity identity)
        {
            if (identity.HasAttribute(DKSaml20BasicPrivilegeProfileIntermediateAttribute.NAME))
            {
                var intermetiateProfiles = identity[DKSaml20BasicPrivilegeProfileIntermediateAttribute.NAME];
                foreach (var profile64 in intermetiateProfiles)
                {
                    var basicPrivilegeProfileXml = Encoding.UTF8.GetString(Convert.FromBase64String(profile64.AttributeValue[0]));
                    var basicPrivilegeProfile    = Serialization.DeserializeFromXmlString <PrivilegeListType>(basicPrivilegeProfileXml);

                    foreach (var privilegeGroup in basicPrivilegeProfile.PrivilegeGroups)
                    {
                        foreach (var privilege in privilegeGroup.Privilege)
                        {
                            yield return(new Privilege(privilegeGroup.Scope, privilege, privilegeGroup.Constraint?.Select(x =>
                                                                                                                          new Profiles.BasicPrivilegeProfile.Constraint(x.Name, x.Value))));
                        }
                    }
                }
            }

            if (identity.HasAttribute(DKSaml20BasicPrivilegeProfileSimpleAttribute.NAME))
            {
                var simpleProfiles = identity[DKSaml20BasicPrivilegeProfileSimpleAttribute.NAME];
                foreach (var attribute in simpleProfiles)
                {
                    foreach (var attributeValue in attribute.AttributeValue)
                    {
                        yield return(new Privilege(null, attributeValue));
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private void MatchPrivilege_WhenNoPrivilegeNodeFound_ReturnsValidResult()
        {
            var mockIdentity   = new Saml20Identity(string.Empty, new List <SamlAttribute>(), string.Empty);
            var sut            = Saml20IdentityParser.CreateFrom(mockIdentity);
            var matchPrivilege = sut.MatchPrivilege("dummy");

            Assert.False(matchPrivilege.HasValue);
        }
        /// <summary>
        /// Action performed during login.
        /// </summary>
        /// <param name="handler">The handler initiating the call.</param>
        /// <param name="context">The current http context.</param>
        /// <param name="assertion">The saml assertion of the currently logged in user.</param>
        public void LoginAction(AbstractEndpointHandler handler, HttpContext context, Saml20Assertion assertion)
        {
            Saml20SignonHandler signonhandler = (Saml20SignonHandler)handler;
            IPrincipal          prince        = Saml20Identity.InitSaml20Identity(assertion, signonhandler.RetrieveIDPConfiguration((string)context.Session[Saml20AbstractEndpointHandler.IDPTempSessionKey]));

            Saml20PrincipalCache.AddPrincipal(prince);

            FormsAuthentication.SetAuthCookie(prince.Identity.Name, false);
        }
        /// <summary>
        /// Gets the principal.
        /// </summary>
        /// <returns></returns>
        internal static IPrincipal GetPrincipal()
        {
            var saml20Assertion = GetSaml20AssertionLite();

            if (saml20Assertion != null)
            {
                return(Saml20Identity.InitSaml20Identity(saml20Assertion));
            }
            return(null);
        }
 protected void Application_AuthenticateRequest(object sender, EventArgs e)
 {
     // The OIOSAML.net session could have timed out or the user could have been logget out throug SOAP logout.
     // Sign user out if user was logged in.
     if (!Saml20Identity.IsInitialized() && HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
     {
         FormsAuthentication.SignOut();
         Response.Redirect(Request.RawUrl); // SignOut first have effect on next request.
     }
 }
Ejemplo n.º 7
0
        ///<summary>
        /// Call from SP when using persistent psuedonyme profile
        ///</summary>
        ///<param name="nameid"></param>
        ///<param name="localuserid"></param>
        public static void LogPersistentPseudonymAuthenticated(string nameid, string localuserid)
        {
            string currentAuthLevel = "Unknown";

            if (Saml20Identity.IsInitialized() && Saml20Identity.Current != null)
            {
                currentAuthLevel = Saml20Identity.Current["dk:gov:saml:attribute:AssuranceLevel"][0].AttributeValue[0];
            }

            logEntry(Direction.UNDEFINED, Operation.LOGIN_PERSISTENT_PSEUDONYME, string.Format("Authenticated nameid: {0} as local user id: {1}, auth.level: {2}, session timeout in minutes: {3}", nameid, localuserid, currentAuthLevel, HttpContext.Current.Session.Timeout));
        }
Ejemplo n.º 8
0
        private void RegisterSSO(IKernel kernel)
        {
            kernel.Bind <SsoFlowConfiguration>().ToMethod(_ => new SsoFlowConfiguration(Settings.Default.SsoServiceProviderId)).InSingletonScope();
            kernel.Bind <StsOrganisationIntegrationConfiguration>().ToMethod(_ =>
                                                                             new StsOrganisationIntegrationConfiguration(
                                                                                 Settings.Default.SsoCertificateThumbprint,
                                                                                 Settings.Default.StsOrganisationEndpointHost))
            .InSingletonScope();

            kernel.Bind <ISsoStateFactory>().To <SsoStateFactory>().InCommandScope(Mode);
            kernel.Bind <ISsoFlowApplicationService>().To <SsoFlowApplicationService>().InCommandScope(Mode);
            kernel.Bind <IStsBrugerInfoService>().To <StsBrugerInfoService>().InCommandScope(Mode);
            kernel.Bind <Maybe <ISaml20Identity> >().ToMethod(_ => Saml20Identity.IsInitialized() ? Saml20Identity.Current : Maybe <ISaml20Identity> .None).InCommandScope(Mode);
        }
        public void LogoutAction(AbstractEndpointHandler handler, HttpContext context,
                                 bool IdPInitiated)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // Example of logging required by the requirements SLO1 ("Id of internal user account")
            // Since FormsAuthentication is used in this sample, the user name to log can be found in context.User.Identity.Name
            // The login will be not be cleared until next redirect due to the way FormsAuthentication works, so we will have to check Saml20Identity.IsInitialized() too
            AuditLogging.logEntry(Direction.IN, Operation.LOGOUT, "ServiceProvider logout",
                                  "SP local user id: " + (context.User.Identity.IsAuthenticated ? context.User.Identity.Name : "none") +
                                  " login status: " + Saml20Identity.IsInitialized());
        }
        protected static bool ValidateKombitAttributeProfile(Saml20Identity current)
        {
            if (current == null)
                throw new ArgumentNullException("current");
            if (!current.HasAttribute("dk:gov:saml:attribute:AssuranceLevel"))
                return false;
            if (!current.HasAttribute("dk:gov:saml:attribute:SpecVer"))
                return false;
            if (!current.HasAttribute("dk:gov:saml:attribute:KombitSpecVer"))
                return false;
            if (!current.HasAttribute("dk:gov:saml:attribute:CvrNumberIdentifier"))
                return false;
            if (!current.HasAttribute("dk:gov:saml:attribute:Privileges_intermediate"))
                return false;

            return true;
        }
 /// <summary>
 /// <see cref="IAction.SoapLogoutAction"/>
 /// </summary>
 public void SoapLogoutAction(AbstractEndpointHandler handler, HttpContext context, string userId)
 {
     AuditLogging.logEntry(Direction.IN, Operation.LOGOUT, "ServiceProvider SOAP logout",
                           "IdP user id: " + userId + " login status: " + Saml20Identity.IsInitialized());
 }
Ejemplo n.º 12
0
        private void HandleRequest(HttpContext context)
        {
            Trace.TraceMethodCalled(GetType(), "HandleRequest()");

            //Fetch config object
            SAML20FederationConfig config = SAML20FederationConfig.GetConfig();

            LogoutRequest logoutRequest = null;
            IDPEndPoint   endpoint      = null;
            string        message       = string.Empty;

            //Build the response object
            var response = new Saml20LogoutResponse();

            response.Issuer     = config.ServiceProvider.ID;
            response.StatusCode = Saml20Constants.StatusCodes.Success; // Default success. Is overwritten if something fails.

            if (context.Request.RequestType == "GET")                  // HTTP Redirect binding
            {
                HttpRedirectBindingParser parser = new HttpRedirectBindingParser(context.Request.Url);
                AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST,
                                      string.Format("Binding: redirect, Signature algorithm: {0}  Signature:  {1}, Message: {2}", parser.SignatureAlgorithm, parser.Signature, parser.Message));

                if (!parser.IsSigned)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Signature not present, msg: " + parser.Message);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }

                logoutRequest = parser.LogoutRequest;
                endpoint      = config.FindEndPoint(logoutRequest.Issuer.Value);

                if (endpoint.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Cannot find metadata for IdP: " + logoutRequest.Issuer.Value);
                    // Not able to return a response as we do not know the IdP.
                    HandleError(context, "Cannot find metadata for IdP " + logoutRequest.Issuer.Value);
                    return;
                }

                Saml20MetadataDocument metadata = endpoint.metadata;

                if (!parser.VerifySignature(metadata.GetKeys(KeyTypes.signing)))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Request has been denied. Invalid signature redirect-binding, msg: " + parser.Message);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }

                message = parser.Message;
            }
            else if (context.Request.RequestType == "POST") // HTTP Post binding
            {
                HttpPostBindingParser parser = new HttpPostBindingParser(context);
                AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST,
                                      "Binding: POST, Message: " + parser.Message);

                if (!parser.IsSigned())
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Signature not present, msg: " + parser.Message);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }

                logoutRequest = parser.LogoutRequest;
                endpoint      = config.FindEndPoint(logoutRequest.Issuer.Value);
                if (endpoint.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Cannot find metadata for IdP");
                    // Not able to return a response as we do not know the IdP.
                    HandleError(context, "Cannot find metadata for IdP " + logoutRequest.Issuer.Value);
                    return;
                }

                Saml20MetadataDocument metadata = endpoint.metadata;

                // handle a logout-request
                if (!parser.CheckSignature(metadata.GetKeys(KeyTypes.signing)))
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Request has been denied. Invalid signature post-binding, msg: " + parser.Message);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }

                message = parser.Message;
            }
            else
            {
                //Error: We don't support HEAD, PUT, CONNECT, TRACE, DELETE and OPTIONS
                // Not able to return a response as we do not understand the request.
                HandleError(context, string.Format(Resources.UnsupportedRequestType, context.Request.RequestType));
                return;
            }

            AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, message);

            // Check that idp in session and request matches.
            string idpRequest = logoutRequest.Issuer.Value;

            // SessionFactory.SessionContext.Current.New is never the first call to Current due to the logic in Application_AuthenticateRequest() ... Saml20Identity.IsInitialized()
            // Hence we need to check on Saml20Identity.IsInitialized() instead of using SessionFactory.SessionContext.Current.New.
            bool isOioSamlSessionActive = Saml20Identity.IsInitialized();

            if (isOioSamlSessionActive)
            {
                object idpId = Saml20PrincipalCache.GetSaml20AssertionLite().Issuer;

                if (idpId != null && idpId.ToString() != idpRequest)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, string.Format(Resources.IdPMismatchBetweenRequestAndSession, idpId, idpRequest), message);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }
            }
            else
            {
                // All other status codes than Success results in the IdP throwing an error page. Therefore we return default Success even if we do not have a session.
                AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Session does not exist. Continues the redirect logout procedure with status code success." + idpRequest, message);
            }

            //  Only logout if request is valid and we are working on an existing Session.
            if (Saml20Constants.StatusCodes.Success == response.StatusCode && isOioSamlSessionActive)
            {
                // Execute all actions that the service provider has configured
                DoLogout(context, true);
            }

            // Update the response object with informations that first is available when request has been parsed.
            IDPEndPointElement destination = DetermineEndpointConfiguration(SAMLBinding.REDIRECT, endpoint.SLOEndpoint, endpoint.metadata.SLOEndpoints());

            response.Destination  = destination.Url;
            response.InResponseTo = logoutRequest.ID;

            //Respond using redirect binding
            var shaHashingAlgorithm = SignatureProviderFactory.ValidateShaHashingAlgorithm(endpoint.ShaHashingAlgorithm);

            if (destination.Binding == SAMLBinding.REDIRECT)
            {
                HttpRedirectBindingBuilder builder = new HttpRedirectBindingBuilder();
                builder.RelayState          = context.Request.Params["RelayState"];
                builder.Response            = response.GetXml().OuterXml;
                builder.signingKey          = FederationConfig.GetConfig().SigningCertificate.GetCertificate().PrivateKey;
                builder.ShaHashingAlgorithm = shaHashingAlgorithm;
                string s = destination.Url + "?" + builder.ToQuery();
                context.Response.Redirect(s, true);
                return;
            }

            //Respond using post binding
            if (destination.Binding == SAMLBinding.POST)
            {
                HttpPostBindingBuilder builder = new HttpPostBindingBuilder(destination);
                builder.Action = SAMLAction.SAMLResponse;
                XmlDocument responseDocument   = response.GetXml();
                var         signingCertificate = FederationConfig.GetConfig().SigningCertificate.GetCertificate();
                var         signatureProvider  = SignatureProviderFactory.CreateFromShaHashingAlgorithmName(shaHashingAlgorithm);
                signatureProvider.SignAssertion(responseDocument, response.ID, signingCertificate);
                builder.Response   = responseDocument.OuterXml;
                builder.RelayState = context.Request.Params["RelayState"];
                builder.GetPage().ProcessRequest(context);
                return;
            }
        }
Ejemplo n.º 13
0
 public void LogoutAction(AbstractEndpointHandler handler, HttpContext context, bool IdPInitiated)
 {
     AuditLogging.logEntry(Direction.IN, Operation.LOGOUT, "ServiceProvider logout",
                           "SP local user id: " + (context.User.Identity.IsAuthenticated ? context.User.Identity.Name : "none") + " login status: " + Saml20Identity.IsInitialized());
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Action performed during SignOn.
        /// </summary>
        /// <param name="handler">The handler initiating the call.</param>
        /// <param name="context">The current http context.</param>
        /// <param name="assertion">The SAML assertion of the currently logged in user.</param>
        public void SignOnAction(AbstractEndpointHandler handler, HttpContext context, Saml20Assertion assertion)
        {
            var signonhandler = (Saml20SignonHandler)handler;

            Saml20PrincipalCache.AddPrincipal(Saml20Identity.InitSaml20Identity(assertion, signonhandler.RetrieveIDPConfiguration(_stateService.Get <string>(Saml20AbstractEndpointHandler.IdpTempSessionKey))));
        }