public ResourceParameterBinding(
     ScimServerConfiguration serverConfiguration,
     HttpParameterDescriptor parameter)
     : base(parameter)
 {
     _ServerConfiguration = serverConfiguration;
 }
Пример #2
0
        private void ConfigureHttpConfiguration(ScimServerConfiguration serverConfiguration)
        {
            var httpConfiguration = serverConfiguration.HttpConfiguration;

            httpConfiguration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
            httpConfiguration.MapHttpAttributeRoutes();

            var settings = httpConfiguration.Formatters.JsonFormatter.SerializerSettings;

            settings.ContractResolver = new ScimContractResolver(serverConfiguration)
            {
                IgnoreSerializableAttribute = true,
                IgnoreSerializableInterface = true
            };
            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            settings.Converters.Add(new StringEnumConverter());
            settings.Converters.Add(new ScimQueryOptionsConverter(serverConfiguration));
            settings.Converters.Add(new ResourceJsonConverter(serverConfiguration, JsonSerializer.Create(settings)));

            httpConfiguration.Filters.Add(new ScimAuthorizationAttribute(serverConfiguration));

            httpConfiguration.ParameterBindingRules.Insert(
                0,
                descriptor =>
            {
                if (typeof(Resource).IsAssignableFrom(descriptor.ParameterType))
                {
                    return(new ResourceParameterBinding(serverConfiguration, descriptor));
                }

                return(null);
            });
            httpConfiguration.ParameterBindingRules.Insert(
                1,
                descriptor =>
            {
                if (typeof(ScimQueryOptions).IsAssignableFrom(descriptor.ParameterType))
                {
                    return(new ScimQueryOptionsParameterBinding(descriptor, serverConfiguration));
                }

                return(null);
            });

            // refer to https://tools.ietf.org/html/rfc7644#section-3.1
            httpConfiguration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/scim+json"));

            // See if user already provided an exception handler
            if (!(httpConfiguration.Services.GetService(typeof(IExceptionHandler)) is OwinScimExceptionHandler))
            {
                httpConfiguration.Services.Replace(typeof(IExceptionHandler), new OwinScimExceptionHandler());
            }
            httpConfiguration.Services.Replace(typeof(IHttpControllerTypeResolver), new DefaultHttpControllerTypeResolver(IsControllerType));
            httpConfiguration.Services.Replace(typeof(IHttpControllerSelector), new ScimHttpControllerSelector(httpConfiguration));

            httpConfiguration.Filters.Add(new ModelBindingResponseAttribute());
        }
        public ScimResourceTypeDefinitionBuilder(
            ScimServerConfiguration serverConfiguration,
            string name,
            string schema,
            string endpoint,
            Type validatorType,
            SchemaBindingPredicate schemaBindingPredicate)
            : base(serverConfiguration, schema)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException("name");
            }

            if (string.IsNullOrWhiteSpace(schema))
            {
                throw new ArgumentNullException("schema");
            }

            if (string.IsNullOrWhiteSpace(endpoint))
            {
                throw new ArgumentNullException("endpoint");
            }

            if (validatorType == null)
            {
                throw new ArgumentNullException("validatorType");
            }

            if (schemaBindingPredicate == null)
            {
                throw new ArgumentNullException("schemaBindingPredicate");
            }

            if (!schema.StartsWith(ScimConstants.Defaults.URNPrefix, StringComparison.OrdinalIgnoreCase))
            {
                throw new Exception("Resource types define a schema identifier which starts with \"" + ScimConstants.Defaults.URNPrefix + "\" as per RFC2141.");
            }

            _SchemaExtensions = new Dictionary <string, ScimResourceTypeExtension>();

            if (!endpoint.StartsWith("/"))
            {
                endpoint = endpoint.Insert(0, "/");
            }

            _Endpoint               = endpoint;
            _ValidatorType          = validatorType;
            _SchemaBindingPredicate = schemaBindingPredicate;

            SetName(name);
        }
Пример #4
0
        public ScimTypeDefinitionBuilder(ScimServerConfiguration serverConfiguration)
        {
            _ServerConfiguration  = serverConfiguration;
            _AttributeDefinitions = BuildDefaultTypeDefinitions();

            var descriptionAttr = TypeDescriptor
                                  .GetAttributes(typeof(T))
                                  .Cast <Attribute>()
                                  .SingleOrDefault(attr => attr is DescriptionAttribute) as DescriptionAttribute;

            if (descriptionAttr != null)
            {
                SetDescription(descriptionAttr.Description.RemoveMultipleSpaces());
            }
        }
Пример #5
0
        public void Configure(ApplicationConfigurationBase applicationConfiguration)
        {
            if (IsConfigured)
            {
                return;
            }

            var serverConfiguration = new ScimServerConfiguration();

            applicationConfiguration.CompositionContainer.ComposeExportedValue(serverConfiguration);

            // configure appBuilder middleware
            AppBuilder.Use <ExceptionHandlerMiddleware>(); // global exception handler for returning SCIM-formatted messages
            AppBuilder.Use((context, task) =>
            {
                AmbientRequestService.SetRequestInformation(context, serverConfiguration);

                return(task.Invoke());
            });

            // discover and register all type definitions
            var versionedSchemaTypes = new Dictionary <ScimVersion, IList <Type> >
            {
                { ScimVersion.One, new List <Type>() },
                { ScimVersion.Two, new List <Type>() }
            };

            var typeDefinitions = applicationConfiguration.CompositionContainer.GetExportTypesThatImplement <IScimTypeDefinition>();

            foreach (var typeDefinition in typeDefinitions)
            {
                Type distinctTypeDefinition;
                var  typeDefinitionTarget = GetTargetDefinitionType(typeDefinition); // the type of object being defined (e.g. User, Group, Name)
                if (serverConfiguration.TypeDefinitionRegistry.TryGetValue(typeDefinitionTarget, out distinctTypeDefinition))
                {
                    // already have a definition registered for the target type
                    // let's favor non-Owin.Scim definitions over built-in defaults
                    if (distinctTypeDefinition.Assembly.FullName.StartsWith(BuiltInAssemblyNamePrefix) &&
                        !typeDefinition.Assembly.FullName.StartsWith(BuiltInAssemblyNamePrefix))
                    {
                        serverConfiguration.TypeDefinitionRegistry[typeDefinitionTarget] = typeDefinition;
                    }

                    continue;
                }

                // register type definition
                if (typeof(IScimSchemaTypeDefinition).IsAssignableFrom(typeDefinition))
                {
                    var targetVersion = typeDefinitionTarget.Namespace.GetScimVersion() ?? serverConfiguration.DefaultScimVersion;
                    versionedSchemaTypes[targetVersion].Add(typeDefinitionTarget);
                }

                serverConfiguration.TypeDefinitionRegistry[typeDefinitionTarget] = typeDefinition;
            }

            serverConfiguration.SchemaTypeVersionCache = versionedSchemaTypes;

            // instantiate an instance of each type definition and add it to configuration
            // type definitions MAY instantiate new type definitions themselves during attribute definition composition
            var enumerator = serverConfiguration.TypeDefinitionRegistry.Values.GetEnumerator();

            while (enumerator.MoveNext())
            {
                // creating type definitions may be expensive due to reflection
                // when a type definition is instantiated, it may implicitly instantiate/register other type
                // definitions for complex attributes, therefore, no need to re-create the same definition more than once
                if (serverConfiguration.ContainsTypeDefinition(enumerator.Current))
                {
                    continue;
                }

                var typeDefinition = (IScimTypeDefinition)enumerator.Current.CreateInstance(serverConfiguration);
                serverConfiguration.AddTypeDefiniton(typeDefinition);
            }

            // define a new HttpConfiguration
            var httpConfiguration = serverConfiguration.HttpConfiguration = new HttpConfiguration();

            // invoke custom configuration action if not null
            if (_ConfigureScimServerAction != null)
            {
                _ConfigureScimServerAction.Invoke(serverConfiguration);
            }

            // register any optional middleware
            if (serverConfiguration.RequireSsl)
            {
                AppBuilder.Use <RequireSslMiddleware>();
            }

            // create a DryIoC container with an optional fallback dependency resolver if one has been specified
            if (serverConfiguration.DependencyResolver != null)
            {
                Container = new Container(
                    rules =>
                    rules.WithoutThrowIfDependencyHasShorterReuseLifespan()
                    .WithUnknownServiceResolvers(request =>
                {
                    var shouldResolve = _TypeResolverCache.GetOrAdd(
                        request.ServiceType,
                        type =>
                        _CompositionConstraints.Any(
                            constraint =>
                            constraint(new FileInfo(type.Assembly.Location))));

                    if (!shouldResolve)
                    {
                        return(null);
                    }

                    return(new DelegateFactory(
                               resolver =>
                               serverConfiguration.DependencyResolver.Resolve(request.ServiceType)));
                }),
                    new AsyncExecutionFlowScopeContext());
            }
            else
            {
                Container = new Container(
                    rules => rules.WithoutThrowIfDependencyHasShorterReuseLifespan(),
                    new AsyncExecutionFlowScopeContext());
            }

            // Configure http configuration for SCIM
            ConfigureHttpConfiguration(serverConfiguration);

            // Register our ScimServerConfiguration as a singleton
            Container.RegisterInstance(serverConfiguration, Reuse.Singleton);

            Container.WithWebApi(httpConfiguration);
            AppBuilder.UseWebApi(httpConfiguration);

            IsConfigured = true;
        }