原来想实现SL OOB模式下单点登录模式,服务器使用了AuthenticationDomainService,在IE里(Browser networking stack),一切正常。但OOB模式下
(Client networking stack )每次都只能再次登录,没办法共享cookie.在网上查了一些资料,这个问题实在是解决不了,天生就是这样的机制。
下面是需要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;
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);
}
还有个关键地方要处理一下.重写domianservice的oncreated代码,将COOKIE处理的逻辑进入注入,以后在交互过程中传递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;
}
}
}
调用服务时,各方法之间可以获取身份,但无法实现单点
研究了好几天,只能到此为止。