예제 #1
0
        private static TimeSpan GetExpiration(IDictionary <string, string> props)
        {
            var result = DefaultExpiration;

            if (!props.TryGetValue("expiration", out var expirationString))
            {
                props.TryGetValue(Cfg.Environment.CacheDefaultExpiration, out expirationString);
            }

            if (expirationString != null)
            {
                try
                {
                    var seconds = Convert.ToInt32(expirationString);
                    result = TimeSpan.FromSeconds(seconds);
                    Log.DebugFormat("new expiration value: {0}", seconds);
                }
                catch (Exception ex)
                {
                    Log.ErrorFormat("error parsing expiration value '{0}'", expirationString);
                    throw new ArgumentException($"could not parse expiration '{expirationString}' as a number of seconds", ex);
                }
            }
            else
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("no expiration value given, using defaults");
                }
            }
            return(result);
        }
예제 #2
0
        public void ValidateLogoutRequest(string requestType, System.Collections.Specialized.NameValueCollection requestParams, Uri requestUrl)
        {
            logger.DebugFormat(TraceMessages.LogoutResponseReceived);

            var            message  = string.Empty;
            LogoutResponse response = null;

            switch (requestType)
            {
            case "GET":
                ValidateLogoutViaGet(requestUrl, out message, out response);
                break;

            case "POST":
                ValidateLogoutViaPost(requestParams, out message, out response);
                break;

            default:
                break;
            }

            if (response == null)
            {
                logger.ErrorFormat(ErrorMessages.UnsupportedRequestType, requestType);
                throw new Saml20Exception(string.Format(ErrorMessages.UnsupportedRequestType, requestType));
            }

            logger.DebugFormat(TraceMessages.LogoutResponseParsed, message);

            if (response.Status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                logger.ErrorFormat(ErrorMessages.ResponseStatusNotSuccessful, response.Status.StatusCode.Value);
                throw new Saml20Exception(string.Format(ErrorMessages.ResponseStatusNotSuccessful, response.Status.StatusCode.Value));
            }
        }
예제 #3
0
        /// <summary>
        /// Handles the SOAP message.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="inputStream">The input stream.</param>
        private async Task HandleSoap(IOwinContext context, Stream inputStream, NameValueCollection requestParams)
        {
            var config = options.Configuration;

            var parser = new HttpArtifactBindingParser(inputStream);

            Logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml);

            var builder = GetBuilder(context);
            var idp     = IdpSelectionUtil.RetrieveIDPConfiguration(parser.Issuer, config);

            if (parser.IsLogoutReqest)
            {
                Logger.DebugFormat(TraceMessages.LogoutRequestReceived, parser.SamlMessage.OuterXml);

                if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys))
                {
                    Logger.ErrorFormat(ErrorMessages.ArtifactResolveSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.ArtifactResolveSignatureInvalid);
                }

                var req = parser.LogoutRequest;

                var logoutRequestReceivedNotification = new LogoutRequestReceivedNotification <LogoutRequest, SamlAuthenticationOptions>(context, options)
                {
                    ProtocolMessage = req
                };

                await options.Notifications.LogoutRequestReceived(logoutRequestReceivedNotification);

                DoLogout(context, true);

                // Build the response object
                var response = new Saml20LogoutResponse
                {
                    Issuer       = config.ServiceProvider.Id,
                    StatusCode   = Saml20Constants.StatusCodes.Success,
                    InResponseTo = req.Id
                };

                // response.Destination = destination.Url;
                var doc = response.GetXml();
                XmlSignatureUtils.SignDocument(doc, response.Id, config.ServiceProvider.SigningCertificate);
                if (doc.FirstChild is XmlDeclaration)
                {
                    doc.RemoveChild(doc.FirstChild);
                }

                SendResponseMessage(doc.OuterXml, context);
            }
            else
            {
                Logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
                throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
            }
        }
예제 #4
0
        /// <summary>
        /// Checks for replay attack.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        public static void CheckReplayAttack(XmlElement element, bool requireInResponseTo, IDictionary<string, object> session)
        {
            logger.Debug(TraceMessages.ReplayAttackCheck);

            var inResponseToAttribute = element.Attributes["InResponseTo"];
            if (!requireInResponseTo && inResponseToAttribute == null) {
                return;
            }
            if (inResponseToAttribute == null) {
                throw new Saml20Exception(ErrorMessages.ResponseMissingInResponseToAttribute);
            }

            var inResponseTo = inResponseToAttribute.Value;
            if (string.IsNullOrEmpty(inResponseTo)) {
                throw new Saml20Exception(ErrorMessages.ExpectedInResponseToEmpty);
            }

            if (session != null) {
                if (!session.ContainsKey(ExpectedInResponseToSessionKey)) {
                    throw new Saml20Exception(ErrorMessages.ExpectedInResponseToMissing);
                }
                var expectedInResponseTo = (string)session[ExpectedInResponseToSessionKey];

                if (inResponseTo != expectedInResponseTo) {
                    logger.ErrorFormat(ErrorMessages.ReplayAttack, inResponseTo, expectedInResponseTo);
                    throw new Saml20Exception(string.Format(ErrorMessages.ReplayAttack, inResponseTo, expectedInResponseTo));
                }
            } else {
                if (!expectedResponses.Contains(inResponseTo)) {
                    throw new Saml20Exception(ErrorMessages.ExpectedInResponseToMissing);
                }
                expectedResponses.Remove(inResponseTo);
            }
            logger.Debug(TraceMessages.ReplaceAttackCheckCleared);
        }
예제 #5
0
        /// <summary>
        /// Performs the attribute query against the specified IdP endpoint and adds the resulting attributes to <c>Saml20Identity.Current</c>.
        /// </summary>
        /// <param name="context">The http context.</param>
        /// <param name="endPoint">The IdP to perform the query against.</param>
        /// <param name="nameIdFormat">The name id format.</param>
        public void PerformQuery(HttpContext context, IdentityProviderElement endPoint, string nameIdFormat)
        {
            Logger.DebugFormat("{0}.{1} called", GetType(), "PerformQuery()");

            var builder = new HttpSoapBindingBuilder(context);

            var name = new NameId
            {
                Value  = Saml20Identity.Current.Name,
                Format = nameIdFormat
            };

            _attrQuery.Subject.Items = new object[] { name };
            _attrQuery.SamlAttribute = _attributes.ToArray();

            var query = new XmlDocument();

            query.LoadXml(Serialization.SerializeToXmlString(_attrQuery));

            XmlSignatureUtils.SignDocument(query, Id);
            if (query.FirstChild is XmlDeclaration)
            {
                query.RemoveChild(query.FirstChild);
            }

            Logger.DebugFormat(TraceMessages.AttrQuerySent, endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml);

            Stream s;

            try
            {
                s = builder.GetResponse(endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml, endPoint.AttributeQuery);
            }
            catch (Exception e)
            {
                Logger.Error(e.Message, e);
                throw;
            }

            var parser = new HttpSoapBindingParser(s);
            var status = parser.GetStatus();

            if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                Logger.ErrorFormat(ErrorMessages.AttrQueryStatusNotSuccessful, Serialization.SerializeToXmlString(status));
                throw new Saml20Exception(status.StatusMessage);
            }

            bool isEncrypted;
            var  xmlAssertion = Saml20SignonHandler.GetAssertion(parser.SamlMessage, out isEncrypted);

            if (isEncrypted)
            {
                var ass = new Saml20EncryptedAssertion((RSA)Saml2Config.GetConfig().ServiceProvider.SigningCertificat
예제 #6
0
        public virtual void Put(object key, object value)
        {
            key.ThrowIfNull("key");
            value.ThrowIfNull("value");

            log.DebugFormat("put in cache: regionName='{0}', key='{1}'", RegionName, key);

            try
            {
                var serializedValue = options.Serializer.Serialize(value);

                var cacheKey           = CacheNamespace.GetKey(key);
                var setOfActiveKeysKey = CacheNamespace.GetSetOfActiveKeysKey();
                var db = GetDatabase();

                db.ScriptEvaluate(putScript, new
                {
                    key = cacheKey,
                    setOfActiveKeysKey = setOfActiveKeysKey,
                    value      = serializedValue,
                    expiration = expiration.TotalMilliseconds
                }, fireAndForgetFlags);
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not put in cache: regionName='{0}', key='{1}'", RegionName, key);

                var evtArg = new ExceptionEventArgs(RegionName, RedisCacheMethod.Put, e);
                options.OnException(this, evtArg);
                if (evtArg.Throw)
                {
                    throw new RedisCacheException(RegionName, "Failed to put item in cache. See inner exception.", e);
                }
            }
        }
예제 #7
0
        private static void VerifyCanInterceptPropertiesForLazyOrGhostProperties(PersistentClass persistentClass)
        {
            foreach (var prop in persistentClass.PropertyClosureIterator)
            {
                if (prop.IsLazy == false &&
                    prop.UnwrapProxy == false)
                {
                    continue;
                }

                var getter = prop.GetGetter(persistentClass.MappedClass);
                if (getter.Method == null ||
                    getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false)
                {
                    log.ErrorFormat("Lazy or ghost property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name);
                }
            }
        }
예제 #8
0
        internal Task WriteMetadataDocument(IOwinContext context)
        {
            var    encoding    = Encoding.UTF8;
            string encodingStr = null;

            try {
                encodingStr = context.Request.Query.Get("encoding");
                if (!string.IsNullOrEmpty(encodingStr))
                {
                    encoding = Encoding.GetEncoding(encodingStr);
                    context.Response.Headers["Content-Encoding"] = encoding.ToString();
                }
            }
            catch (ArgumentException ex) {
                logger.ErrorFormat(ErrorMessages.UnknownEncoding, encodingStr);
                throw new ArgumentException(string.Format(ErrorMessages.UnknownEncoding, encodingStr), ex);
            }

            var sign  = true;
            var param = context.Request.Query.Get("sign");

            if (!string.IsNullOrEmpty(param))
            {
                if (!bool.TryParse(param, out sign))
                {
                    throw new ArgumentException(ErrorMessages.MetadataSignQueryParameterInvalid);
                }
            }

            context.Response.ContentType = "application/samlmetadata+xml"; //Saml20Constants.MetadataMimetype; - that will prompt a download

            var filename = context.Request.Query.Get("file");

            if (!string.IsNullOrWhiteSpace(filename))
            {
                context.Response.Headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", filename);
            }

            var metautil = new MetadataUtils(configuration, logger);

            return(context.Response.WriteAsync(metautil.CreateMetadataDocument(encoding, sign)));
        }
        protected void SyncGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    CacheNamespace.SetGeneration(FetchGeneration());
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
예제 #10
0
        private void SyncInitialGeneration()
        {
            try
            {
                if (CacheNamespace.GetGeneration() == -1)
                {
                    var latestGeneration = FetchGeneration();
                    CacheNamespace.SetHigherGeneration(latestGeneration);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("could not sync initial generation");

                var evtArg = new RedisCacheExceptionEventArgs(e);
                OnException(evtArg);
                if (evtArg.Throw)
                {
                    throw;
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Configures the cache region from configuration values
        /// </summary>
        /// <param name="settings">Configuration settings for the region</param>
        /// <param name="additionalProperties">The additional properties supplied by NHibernate engine</param>
        private void Configure(CacheRegionElement settings, IDictionary <string, string> additionalProperties)
        {
            log.Debug("Configuring cache region");

            //these are some default conenction values that can be later used by the data dependencies
            //if no custome settings are specified
            string connectionName    = null;
            string connectionString  = null;
            string expirationString  = null;
            var    defaultExpiration = defaultRelativeExpiration;

            if (additionalProperties != null)
            {
                //pick up connection settings that might be used later for data dependencis if any are specified
                if (additionalProperties.ContainsKey(Environment.ConnectionStringName))
                {
                    connectionName = additionalProperties[Environment.ConnectionStringName];
                }

                if (additionalProperties.ContainsKey(Environment.ConnectionString))
                {
                    connectionString = additionalProperties[Environment.ConnectionString];
                }

                if (additionalProperties.ContainsKey(Environment.CacheDefaultExpiration))
                {
                    expirationString = additionalProperties[Environment.CacheDefaultExpiration];
                }

                if (!string.IsNullOrEmpty(expirationString))
                {
                    try
                    {
                        var seconds = Convert.ToInt32(expirationString);
                        defaultExpiration = TimeSpan.FromSeconds(seconds);
                        log.DebugFormat("default expiration value: {0}", seconds);
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("error parsing expiration value '{0}'", expirationString);
                        throw new ArgumentException($"could not parse expiration '{expirationString}' as a number of seconds", ex);
                    }
                }
            }

            if (settings != null)
            {
                _priority            = settings.Priority;
                _timeOfDayExpiration = settings.TimeOfDayExpiration;
                _relativeExpiration  = settings.RelativeExpiration;

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("using priority: {0}", settings.Priority.ToString("g"));

                    if (_relativeExpiration.HasValue)
                    {
                        log.DebugFormat("using relative expiration :{0}", _relativeExpiration);
                    }

                    if (_timeOfDayExpiration.HasValue)
                    {
                        log.DebugFormat("using time of day expiration : {0}", _timeOfDayExpiration);
                    }
                }

                CreateDependencyEnlisters(settings.Dependencies, connectionName, connectionString);
            }
            else
            {
                _priority = CacheItemPriority.Default;

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("no priority specified using default : {0}", _priority.ToString("g"));
                }
            }

            //use the default expiration of no expiration was set
            if (_relativeExpiration.HasValue == false && _timeOfDayExpiration.HasValue == false)
            {
                _relativeExpiration = defaultExpiration;

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("no expiration specified using default : {0}", _relativeExpiration);
                }
            }
        }
예제 #12
0
 public virtual ActionResult NotFound(string entityName)
 {
     _log.ErrorFormat("Not found entity ({0}).", entityName);
     return(Content("not found"));
 }
예제 #13
0
파일: Utility.cs 프로젝트: ahydrax/SAML2
        /// <summary>
        /// Handles the SOAP.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="inputStream">The input stream.</param>
        public static void HandleSoap(HttpArtifactBindingBuilder builder, Stream inputStream, Saml2Configuration config, Action <Saml20Assertion> signonCallback, Func <string, object> getFromCache, Action <string, object, DateTime> setInCache, IDictionary <string, object> session)
        {
            var parser = new HttpArtifactBindingParser(inputStream);

            logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml);

            if (parser.IsArtifactResolve)
            {
                logger.Debug(TraceMessages.ArtifactResolveReceived);

                var idp = IdpSelectionUtil.RetrieveIDPConfiguration(parser.Issuer, config);
                if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys))
                {
                    logger.Error(ErrorMessages.ArtifactResolveSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.ArtifactResolveSignatureInvalid);
                }

                builder.RespondToArtifactResolve(parser.ArtifactResolve, ((XmlDocument)getFromCache(parser.ArtifactResolve.Artifact)).DocumentElement);
            }
            else if (parser.IsArtifactResponse)
            {
                logger.Debug(TraceMessages.ArtifactResolveReceived);

                var idp = IdpSelectionUtil.RetrieveIDPConfiguration(parser.Issuer, config);
                if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys))
                {
                    logger.Error(ErrorMessages.ArtifactResponseSignatureInvalid);
                    throw new Saml20Exception(ErrorMessages.ArtifactResponseSignatureInvalid);
                }

                var status = parser.ArtifactResponse.Status;
                if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
                {
                    logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value);
                    throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value));
                }

                if (parser.ArtifactResponse.Any.LocalName == Response.ElementName)
                {
                    Utility.CheckReplayAttack(parser.ArtifactResponse.Any, true, session);

                    var responseStatus = Utility.GetStatusElement(parser.ArtifactResponse.Any);
                    if (responseStatus.StatusCode.Value != Saml20Constants.StatusCodes.Success)
                    {
                        logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value);
                        throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value));
                    }

                    bool isEncrypted;
                    var  assertion = Utility.GetAssertion(parser.ArtifactResponse.Any, out isEncrypted);
                    if (assertion == null)
                    {
                        logger.Error(ErrorMessages.ArtifactResponseMissingAssertion);
                        throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingAssertion);
                    }

                    var samlAssertion = isEncrypted
                        ? Utility.HandleEncryptedAssertion(assertion, config, getFromCache, setInCache)
                        : Utility.HandleAssertion(assertion, config, getFromCache, setInCache);
                    signonCallback(samlAssertion);
                }
                else
                {
                    logger.ErrorFormat(ErrorMessages.ArtifactResponseMissingResponse);
                    throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingResponse);
                }
            }
            else
            {
                logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
                throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage);
            }
        }
예제 #14
0
        public void Log(NHibernateLogLevel logLevel, NHibernateLogValues state, Exception exception)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            switch (logLevel)
            {
            case NHibernateLogLevel.Debug:
            case NHibernateLogLevel.Trace:
                if (exception != null)
                {
                    _internalLogger.Debug(state, exception);
                }
                else if (state.Args?.Length > 0)
                {
                    _internalLogger.DebugFormat(state.Format, state.Args);
                }
                else
                {
                    _internalLogger.Debug(state);
                }
                break;

            case NHibernateLogLevel.Info:
                if (exception != null)
                {
                    _internalLogger.Info(state, exception);
                }
                else if (state.Args?.Length > 0)
                {
                    _internalLogger.InfoFormat(state.Format, state.Args);
                }
                else
                {
                    _internalLogger.Info(state);
                }
                break;

            case NHibernateLogLevel.Warn:
                if (exception != null)
                {
                    _internalLogger.Warn(state, exception);
                }
                else if (state.Args?.Length > 0)
                {
                    _internalLogger.WarnFormat(state.Format, state.Args);
                }
                else
                {
                    _internalLogger.Warn(state);
                }
                break;

            case NHibernateLogLevel.Error:
                if (exception != null)
                {
                    _internalLogger.Error(state, exception);
                }
                else if (state.Args?.Length > 0)
                {
                    _internalLogger.ErrorFormat(state.Format, state.Args);
                }
                else
                {
                    _internalLogger.Error(state);
                }
                break;

            case NHibernateLogLevel.Fatal:
                if (exception != null)
                {
                    _internalLogger.Fatal(state, exception);
                }
                else
                {
                    _internalLogger.Fatal(state);
                }
                break;

            case NHibernateLogLevel.None:
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
            }
        }
예제 #15
0
        /// <summary>
        /// Configures the cache region from configuration values
        /// </summary>
        /// <param name="settings">Configuration settings for the region</param>
        /// <param name="additionalProperties">The additional properties supplied by NHibernate engine</param>
        private void Configure(CacheRegionElement settings, IDictionary <string, string> additionalProperties)
        {
            Log.Debug("Configuring cache region");

            // these are some default connection values that can be later used by the data dependencies
            // if no custom settings are specified
            string connectionName    = null;
            string connectionString  = null;
            var    defaultExpiration = DefaultRelativeExpiration;

            _useSlidingExpiration = _defaultUseSlidingExpiration;

            if (additionalProperties != null)
            {
                // pick up connection settings that might be used later for data dependencis if any are specified
                if (additionalProperties.ContainsKey(Environment.ConnectionStringName))
                {
                    connectionName = additionalProperties[Environment.ConnectionStringName];
                }

                if (additionalProperties.ContainsKey(Environment.ConnectionString))
                {
                    connectionString = additionalProperties[Environment.ConnectionString];
                }

                if (!additionalProperties.TryGetValue("expiration", out var expirationString))
                {
                    additionalProperties.TryGetValue(Environment.CacheDefaultExpiration, out expirationString);
                }

                if (expirationString != null)
                {
                    try
                    {
                        var seconds = Convert.ToInt32(expirationString);
                        defaultExpiration = TimeSpan.FromSeconds(seconds);
                        Log.DebugFormat("default expiration value: {0}", seconds);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorFormat("error parsing expiration value '{0}'", expirationString);
                        throw new ArgumentException($"could not parse expiration '{expirationString}' as a number of seconds", ex);
                    }
                }

                _useSlidingExpiration = PropertiesHelper.GetBoolean("cache.use_sliding_expiration", additionalProperties, _defaultUseSlidingExpiration);
                Log.DebugFormat("default sliding expiration value: {0}", _useSlidingExpiration);
            }

            if (settings != null)
            {
                _priority             = settings.Priority;
                _timeOfDayExpiration  = settings.TimeOfDayExpiration;
                _relativeExpiration   = settings.RelativeExpiration;
                _useSlidingExpiration = settings.UseSlidingExpiration ?? _useSlidingExpiration;

                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("using priority: {0:g}", settings.Priority);

                    if (_relativeExpiration.HasValue)
                    {
                        Log.DebugFormat("using relative expiration: {0}{1}", _relativeExpiration, _useSlidingExpiration ? " (sliding)" : string.Empty);
                    }

                    if (_timeOfDayExpiration.HasValue)
                    {
                        Log.DebugFormat("using time of day expiration: {0}", _timeOfDayExpiration);
                    }
                }

                CreateDependencyEnlisters(settings.Dependencies, connectionName, connectionString);
            }
            else
            {
                _priority = CacheItemPriority.Default;

                Log.DebugFormat("no priority specified, using default: {0:g}", _priority);
            }

            //use the default expiration as no expiration was set
            if (_relativeExpiration.HasValue == false && _timeOfDayExpiration.HasValue == false)
            {
                _relativeExpiration = defaultExpiration;

                Log.DebugFormat("no expiration specified, using default: {0}", _relativeExpiration);
            }
        }
예제 #16
0
        public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory)
        {
            this.sessionFactory = sessionFactory;


            name       = persistentClass.EntityName;
            rootName   = persistentClass.RootClazz.EntityName;
            entityType = TypeFactory.ManyToOne(name);
            type       = persistentClass.MappedClass;
            rootType   = persistentClass.RootClazz.MappedClass;
            rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName;

            identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass,
                                                                         sessionFactory.GetIdentifierGenerator(rootName));

            versioned = persistentClass.IsVersioned;

            bool lazyAvailable = persistentClass.HasPocoRepresentation &&
                                 FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass);
            bool hasLazy = false;

            propertySpan = persistentClass.PropertyClosureSpan;
            properties   = new StandardProperty[propertySpan];
            List <int> naturalIdNumbers = new List <int>();

            propertyNames                = new string[propertySpan];
            propertyTypes                = new IType[propertySpan];
            propertyUpdateability        = new bool[propertySpan];
            propertyInsertability        = new bool[propertySpan];
            insertInclusions             = new ValueInclusion[propertySpan];
            updateInclusions             = new ValueInclusion[propertySpan];
            nonlazyPropertyUpdateability = new bool[propertySpan];
            propertyCheckability         = new bool[propertySpan];
            propertyNullability          = new bool[propertySpan];
            propertyVersionability       = new bool[propertySpan];
            propertyLaziness             = new bool[propertySpan];
            cascadeStyles                = new CascadeStyle[propertySpan];

            int  i = 0;
            int  tempVersionProperty               = NoVersionIndex;
            bool foundCascade                      = false;
            bool foundCollection                   = false;
            bool foundMutable                      = false;
            bool foundInsertGeneratedValue         = false;
            bool foundUpdateGeneratedValue         = false;
            bool foundNonIdentifierPropertyNamedId = false;

            HasPocoRepresentation = persistentClass.HasPocoRepresentation;

            // NH: WARNING if we have to disable lazy/unproxy properties we have to do it in the whole process.
            lazy           = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface));
            lazyAvailable &= lazy;             // <== Disable lazy properties if the class is marked with lazy=false

            bool hadLazyProperties   = false;
            bool hadNoProxyRelations = false;

            foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator)
            {
                if (prop.IsLazy)
                {
                    hadLazyProperties = true;
                }
                if (prop.UnwrapProxy)
                {
                    hadNoProxyRelations = true;
                }

                // NH: A lazy property is a simple property marked with lazy=true
                bool islazyProperty = prop.IsLazy && lazyAvailable && (!prop.IsEntityRelation || prop.UnwrapProxy);
                // NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy"
                var isUnwrapProxy = prop.UnwrapProxy && lazyAvailable;

                if (islazyProperty || isUnwrapProxy)
                {
                    // NH: verify property proxiability
                    var getter = prop.GetGetter(persistentClass.MappedClass);
                    if (getter.Method == null || getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false)
                    {
                        log.ErrorFormat("Lazy or no-proxy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name);
                    }
                }

                if (prop == persistentClass.Version)
                {
                    tempVersionProperty = i;
                    properties[i]       = PropertyFactory.BuildVersionProperty(prop, islazyProperty);
                }
                else
                {
                    properties[i] = PropertyFactory.BuildStandardProperty(prop, islazyProperty);
                }

                if (prop.IsNaturalIdentifier)
                {
                    naturalIdNumbers.Add(i);
                }

                if ("id".Equals(prop.Name))
                {
                    foundNonIdentifierPropertyNamedId = true;
                }

                if (islazyProperty)
                {
                    hasLazy = true;
                }
                if (isUnwrapProxy)
                {
                    hasUnwrapProxyForProperties = true;
                }

                propertyLaziness[i] = islazyProperty;

                propertyNames[i]                = properties[i].Name;
                propertyTypes[i]                = properties[i].Type;
                propertyNullability[i]          = properties[i].IsNullable;
                propertyUpdateability[i]        = properties[i].IsUpdateable;
                propertyInsertability[i]        = properties[i].IsInsertable;
                insertInclusions[i]             = DetermineInsertValueGenerationType(prop, properties[i]);
                updateInclusions[i]             = DetermineUpdateValueGenerationType(prop, properties[i]);
                propertyVersionability[i]       = properties[i].IsVersionable;
                nonlazyPropertyUpdateability[i] = properties[i].IsUpdateable && !islazyProperty;
                propertyCheckability[i]         = propertyUpdateability[i]
                                                  ||
                                                  (propertyTypes[i].IsAssociationType &&
                                                   ((IAssociationType)propertyTypes[i]).IsAlwaysDirtyChecked);

                cascadeStyles[i] = properties[i].CascadeStyle;

                if (properties[i].IsLazy)
                {
                    hasLazy = true;
                }

                if (properties[i].CascadeStyle != CascadeStyle.None)
                {
                    foundCascade = true;
                }

                if (IndicatesCollection(properties[i].Type))
                {
                    foundCollection = true;
                }

                if (propertyTypes[i].IsMutable && propertyCheckability[i])
                {
                    foundMutable = true;
                }

                if (insertInclusions[i] != ValueInclusion.None)
                {
                    foundInsertGeneratedValue = true;
                }

                if (updateInclusions[i] != ValueInclusion.None)
                {
                    foundUpdateGeneratedValue = true;
                }

                MapPropertyToIndex(prop, i);
                i++;
            }

            if (naturalIdNumbers.Count == 0)
            {
                naturalIdPropertyNumbers = null;
            }
            else
            {
                naturalIdPropertyNumbers = naturalIdNumbers.ToArray();
            }

            hasCascades = foundCascade;
            hasInsertGeneratedValues        = foundInsertGeneratedValue;
            hasUpdateGeneratedValues        = foundUpdateGeneratedValue;
            hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;

            versionPropertyIndex = tempVersionProperty;
            hasLazyProperties    = hasLazy;

            if (hadLazyProperties && !hasLazy)
            {
                log.WarnFormat("Disabled lazy property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasLazy)
            {
                log.Info("lazy property fetching available for: " + name);
            }

            if (hadNoProxyRelations && !hasUnwrapProxyForProperties)
            {
                log.WarnFormat("Disabled ghost property fetching for {0} because it does not support lazy at the entity level", name);
            }
            if (hasUnwrapProxyForProperties)
            {
                log.Info("no-proxy property fetching available for: " + name);
            }

            mutable = persistentClass.IsMutable;

            if (!persistentClass.IsAbstract.HasValue)
            {
                // legacy behavior (with no abstract attribute specified)
                isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass);
            }
            else
            {
                isAbstract = persistentClass.IsAbstract.Value;
                if (!isAbstract && persistentClass.HasPocoRepresentation &&
                    ReflectHelper.IsAbstractClass(persistentClass.MappedClass))
                {
                    log.Warn("entity [" + type.FullName
                             + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names");
                }
            }
            selectBeforeUpdate = persistentClass.SelectBeforeUpdate;
            dynamicUpdate      = persistentClass.DynamicUpdate;
            dynamicInsert      = persistentClass.DynamicInsert;

            polymorphic          = persistentClass.IsPolymorphic;
            explicitPolymorphism = persistentClass.IsExplicitPolymorphism;
            inherited            = persistentClass.IsInherited;
            superclass           = inherited ? persistentClass.Superclass.EntityName : null;
            superclassType       = inherited ? persistentClass.Superclass.MappedClass : null;
            hasSubclasses        = persistentClass.HasSubclasses;

            optimisticLockMode = persistentClass.OptimisticLockMode;
            if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate)
            {
                throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName);
            }

            hasCollections       = foundCollection;
            hasMutableProperties = foundMutable;

            foreach (Subclass obj in persistentClass.SubclassIterator)
            {
                subclassEntityNames.Add(obj.EntityName);
            }
            subclassEntityNames.Add(name);

            EntityMode = persistentClass.HasPocoRepresentation ? EntityMode.Poco : EntityMode.Map;

            var entityTuplizerFactory = new EntityTuplizerFactory();
            var tuplizerClassName     = persistentClass.GetTuplizerImplClassName(EntityMode);

            Tuplizer = tuplizerClassName == null
                                ? entityTuplizerFactory.BuildDefaultEntityTuplizer(EntityMode, this, persistentClass)
                                : entityTuplizerFactory.BuildEntityTuplizer(tuplizerClassName, this, persistentClass);
        }
예제 #17
0
        /// <summary>
        /// Performs the attribute query against the specified IdP endpoint and adds the resulting attributes to <c>Saml20Identity.Current</c>.
        /// </summary>
        /// <param name="context">The http context.</param>
        /// <param name="endPoint">The IdP to perform the query against.</param>
        /// <param name="nameIdFormat">The name id format.</param>
        public void PerformQuery(HttpContext context, IdentityProvider endPoint, string nameIdFormat)
        {
            Logger.DebugFormat("{0}.{1} called", GetType(), "PerformQuery()");

            var builder = new HttpSoapBindingBuilder(context);

            var name = new NameId
            {
                Value  = Saml20Identity.Current.Name,
                Format = nameIdFormat
            };

            _attrQuery.Subject.Items = new object[] { name };
            _attrQuery.SamlAttribute = _attributes.ToArray();

            var query = new XmlDocument();

            query.LoadXml(Serialization.SerializeToXmlString(_attrQuery));

            XmlSignatureUtils.SignDocument(query, Id);
            if (query.FirstChild is XmlDeclaration)
            {
                query.RemoveChild(query.FirstChild);
            }

            Logger.DebugFormat(TraceMessages.AttrQuerySent, endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml);

            Stream s;

            try
            {
                s = builder.GetResponse(endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml, endPoint.AttributeQuery);
            }
            catch (Exception e)
            {
                Logger.Error(e.Message, e);
                throw;
            }

            var parser = new HttpSoapBindingParser(s);
            var status = parser.GetStatus();

            if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                Logger.ErrorFormat(ErrorMessages.AttrQueryStatusNotSuccessful, Serialization.SerializeToXmlString(status));
                throw new Saml20Exception(status.StatusMessage);
            }

            bool isEncrypted;
            var  xmlAssertion = Saml20SignonHandler.GetAssertion(parser.SamlMessage, out isEncrypted);

            if (isEncrypted)
            {
                var ass = new Saml20EncryptedAssertion((RSA)Saml2Config.Current.ServiceProvider.SigningCertificate.GetCertificate().PrivateKey);
                ass.LoadXml(xmlAssertion);
                ass.Decrypt();
                xmlAssertion = ass.Assertion.DocumentElement;
            }

            var assertion = new Saml20Assertion(xmlAssertion, null, Saml2Config.Current.AssertionProfile.AssertionValidator, endPoint.QuirksMode);

            Logger.DebugFormat(TraceMessages.AttrQueryAssertionReceived, xmlAssertion == null ? string.Empty : xmlAssertion.OuterXml);

            if (!assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endPoint.Metadata.Keys, endPoint)))
            {
                Logger.Error(ErrorMessages.AssertionSignatureInvalid);
                throw new Saml20Exception(ErrorMessages.AssertionSignatureInvalid);
            }

            foreach (var attr in assertion.Attributes)
            {
                Saml20Identity.Current.AddAttributeFromQuery(attr.Name, attr);
            }
        }