OpenRIAServices / OpenRiaServices

The Open RIA Services project continues what was previously known as WCF RIA Services.
https://openriaservices.gitbook.io/openriaservices/
Apache License 2.0
54 stars 47 forks source link

The method ApplyClientBehavior inside IEndpointBehavior gets not call after updating openria to 5.3.1 #430

Closed neplan closed 10 months ago

neplan commented 1 year ago

Describe the bug After updating from 4.6 to 5.3.1 the authentication is not working anymore. We have found out thath our SharedCookieHttpBehavior is not working as we expected. The ApplyClientBehavior seems not to be called:

public class SharedCookieHttpBehavior : IEndpointBehavior
    {
        private static readonly CookieContainer Container = new CookieContainer();
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new SharedCookieMessageInspector(Container));
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }
        public void Validate(ServiceEndpoint endpoint)
        {
        }
        public static string GetCookies(string url)
        {
            string cookie = null;
            if(Container != null)
            {
                var uri = new Uri(url);
                cookie = Container.GetCookieHeader(uri);
            }
            return cookie;
        }
        public static void SetCookieContainer(HttpCookie cookie, Uri uri)
        {
            if (string.IsNullOrWhiteSpace(cookie.Domain))                
                cookie.Domain = uri.Host;
            var header = $"{cookie.Name}={cookie.Value}";
            Container.SetCookies(uri, header);
        }
        public static CookieContainer GetCookieContainer()
        {
            return Container;
        }
    }

We are adding this Endpointbehavior in the EndpointBehavior of the channel:

 public static class DomainContextExtensions
    {
        public static void ShareCookieContainer(this DomainContext domainContext)
        {
            // Try to get the channel factory property from the domain client 
            // of the domain context. In case that this property does not exist
            // we throw an invalid operation exception.
            var channelFactoryProperty = domainContext.DomainClient.GetType().GetProperty("ChannelFactory");
            if (channelFactoryProperty == null)
            {
                throw new InvalidOperationException("The 'ChannelFactory' property on the DomainClient does not exist.");
            }

            // Now get the channel factory from the domain client and set the
            // new timeout to the binding of the service endpoint.
            var factory = (ChannelFactory)channelFactoryProperty.GetValue(domainContext.DomainClient, null);
            var httpBinding = ((CustomBinding)factory.Endpoint.Binding).Elements.Find<HttpTransportBindingElement>();
            if (httpBinding != null)
            {
                httpBinding.AllowCookies = true;
            }

            var httpsBinding = ((CustomBinding)factory.Endpoint.Binding).Elements.Find<HttpsTransportBindingElement>();
            if (httpsBinding != null)
            {
                httpsBinding.AllowCookies = true;
            }
            factory.Endpoint.EndpointBehaviors.Add(new SharedCookieHttpBehavior());
        }
    }

Are we missing something?

SandstromErik commented 1 year ago

Hi @neplan, I will have a look at this when I have time, probably in the next couple of days and hopefully find a solution

neplan commented 1 year ago

Hi @SandstromErik . This would be great. Thank you.

SandstromErik commented 1 year ago

I found that the ChannelFactory is opened when retrieving it in the extension method, which means that adding additional EndPointBehaviors will not initialize them, i.e. ApplyClientBehaviour will not be called for the additional behaviour. I am investigating if ChannelFactory needs to be opened or if that code can be removed.

neplan commented 1 year ago

Ok. Thank you.

Am 05.07.2023 17:28, schrieb Erik Sandström:

I found that the ChannelFactory is opened when retrieving it in the extension method, which means that adding additional EndPointBehaviors will not initialize them, i.e. ApplyClientBehaviour will not be called for the additional behaviour. I am investigating if ChannelFactory needs to be opened or if that code can be removed.

Daniel-Svensson commented 1 year ago

If you need to add your custom behaviour you need to write your own DomainClientFactory, se https://github.com/OpenRIAServices/OpenRiaServices/issues/267#issuecomment-779403405 for a similar issue and proposed solution.

Some other notes: