SL OOB 모드에서 COOKIE 처리

6163 단어
원래 SL OOB 모드에서 단일 로그인 모드를 실현하려고 했는데 서버는 Authentication Domain Service를 사용했고 IE(Browser networking stack)에서 모든 것이 정상입니다.하지만 OOB 모드에서는
(Client networking stack) 매번 다시 로그인할 수 있어 cooki를 공유할 수 없습니다.인터넷에서 몇 가지 자료를 찾았는데, 이 문제는 정말 해결할 수 없다. 천성적으로 이런 메커니즘이다.
다음은 쿠키 처리가 필요한 핵심 코드입니다.
 
 
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel.DomainServices.Client;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace ClinetNetStackTest
{
    public static class ClientHttpAuthenticationUtility
    {
        static readonly SharedCookieHttpBehavior sharedCookieBehavior = new SharedCookieHttpBehavior();

        public static void ShareCookieContainer(DomainContext context)
        {
            var channelFactoryProperty = context.DomainClient.GetType().GetProperty("ChannelFactory");
            if (channelFactoryProperty == null)
                throw new InvalidOperationException("There is no 'ChannelFactory' property on the DomainClient.");
            var factory = (ChannelFactory)channelFactoryProperty.GetValue(context.DomainClient, null);
            ((CustomBinding)factory.Endpoint.Binding).Elements.Insert(0, new HttpCookieContainerBindingElement());
            factory.Endpoint.Behaviors.Add(sharedCookieBehavior);
        }

        class SharedCookieHttpBehavior : WebHttpBehavior
        {
            readonly SharedCookieMessageInspector inspector = new SharedCookieMessageInspector();

            public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.MessageInspectors.Add(inspector);
            }
        }

        class SharedCookieMessageInspector : IClientMessageInspector
        {
            public SharedCookieMessageInspector()
            {
            }
            static CookieContainer cookieContainer = new CookieContainer();

            public void AfterReceiveReply(ref Message reply, object correlationState)
            {
#if DEBUG
                    HttpResponseMessageProperty httpResponse =
                        reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
                    if (httpResponse != null)
                    {
                        string cookie = httpResponse.Headers["Set-Cookie"]; //     httponly
                        if (!string.IsNullOrEmpty(cookie))
                        {
                            MessageBox.Show("  Cookie" + cookie);
                        }
#endif
                }                


            }

            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                channel.GetProperty<IHttpCookieContainerManager>().CookieContainer = cookieContainer;
                return null;
            }
        }
    }
}

 
SL의 App에 다음 코드를 추가합니다.
  if (Application.Current.IsRunningOutOfBrowser)
            {
               bool b= WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
               b= WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
            }

아직 처리해야 할 중요한 곳이 있소.domian 서비스의 oncreated 코드를 다시 작성하여 COOKIE 처리의 논리를 주입에 넣고 나중에 상호작용 과정에서 쿠키를 전달합니다
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ClinetNetStackTest.Web.Services
{
    public partial class AuthenticationDomainContext
    {
        partial void OnCreated()
        {
            if (Application.Current.IsRunningOutOfBrowser)
                ClientHttpAuthenticationUtility.ShareCookieContainer(this);
        }
    }
}

 
 
서버측 코드는 다음과 같습니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using System.Web;

namespace ClinetNetStackTest.Web.Services
{
    [EnableClientAccess]
    public class AuthenticationDomainService : AuthenticationBase<User>
    {
        //     Web        Forms/Windows     ,    web.config        。
        public string GetOOBUserName()
        {
            if (HttpContext.Current.Request.Cookies.Count > 0)
            {
                return HttpContext.Current.Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Value;
            }
            else
            {
                return "Not Send Cookie";
            }

        }

        public bool IsAuthenticated()
        {
            return HttpContext.Current.User.Identity.IsAuthenticated;
        }
    }
}

서비스를 호출할 때, 각 방법 간에 신분을 얻을 수 있지만, 단지 며칠 동안 연구한 것은 실현할 수 없고, 여기까지만 할 수 있다.

좋은 웹페이지 즐겨찾기