使用ASP.NET Ajax通过SSL调用WCF
我正在使用ASP.NET Ajax从ASP.NET页面调用WCF。我正在使用表单身份验证来保护网站 在开发过程中,一切都按照预期工作,直到它被部署到生产服务器上,然后我开始出现JavaScript错误,因为找不到该服务。生产服务器正在使用SSL,因此我在web.config中添加了以下内容: 我的使用ASP.NET Ajax通过SSL调用WCF,wcf,asp.net-ajax,web-config,forms-authentication,Wcf,Asp.net Ajax,Web Config,Forms Authentication,我正在使用ASP.NET Ajax从ASP.NET页面调用WCF。我正在使用表单身份验证来保护网站 在开发过程中,一切都按照预期工作,直到它被部署到生产服务器上,然后我开始出现JavaScript错误,因为找不到该服务。生产服务器正在使用SSL,因此我在web.config中添加了以下内容: 我的应用程序中使用的代码\u AuthenticateRequest: protected void Application_AuthenticateRequest(object sender, Event
应用程序中使用的代码\u AuthenticateRequest
:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
String cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if (authCookie == null)
{
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
if (authTicket == null)
{
return;
}
HttpContext.Current.User = new CustomPrinciple(authTicket.Name);
}
简单地将安全性从None更改为Transport不应该影响通过Authenticate\u请求运行的应用程序。您可能应该将调试器附加到服务实现,并查看HttpContext.Current.User是什么。它是您的自定义主体还是未设置?您可能还需要添加几个Debug.Write消息,并查看操作顺序。验证请求事件是否在您预期之后发生 如果在配置中使用
,则可能会遇到-此设置似乎与安全传输不兼容,WCF会覆盖主体。如果您正在设置主体,则似乎需要对其使用principalPermissionMode=“None”
确保您仍然通过配置(
)或通过服务属性([AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]在服务上启用了。否则,服务将无法访问HttpContext.Current
另外,不要在服务实现构造函数中获取HttpContext.Current.User,而是尝试将其移动到附加到服务的行为。实现一个IDispatchMessageInspector
,它处理AfterReceiveRequest
事件,并将主体从web上下文传输到线程。它看起来像这样:
public class HttpContextPrincipalInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (HttpContext.Current != null)
{
IPrincipal principal = HttpContext.Current.User;
Thread.CurrentPrincipal = principal;
}
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState) { }
}
当然,还可以实现一个IEndpointBehavior
来连接dispatcher
public class HttpContextPrincipalBehavior : IEndpointBehavior
{
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
ChannelDispatcher channelDispatcher = endpointDispatcher.ChannelDispatcher;
foreach (EndpointDispatcher endpointDispatch in channelDispatcher.Endpoints)
{
endpointDispatch.DispatchRuntime.MessageInspectors.Add(new HttpContextPrincipalInspector());
}
}
// AddBindingParameters, ApplyClientBehavior, and Validate implementations
// can be empty - they don't do anything.
}
…和自定义的BehaviorExtensionElement
,以便您可以在WCF配置中使用它:
public class HttpContextPrincipalElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(HttpContextPrincipalBehavior); }
}
protected override object CreateBehavior()
{
return new HttpContextPrincipalBehavior();
}
}
然后,您可以配置任何服务以将其用作端点行为,这样服务实现就不会直接与web上下文对话。使测试变得更容易,并且可以完全解决问题-每当服务收到消息时,它都会自动将主体传输到服务器上,而不是依赖于服务的构造
public class HttpContextPrincipalBehavior : IEndpointBehavior
{
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
ChannelDispatcher channelDispatcher = endpointDispatcher.ChannelDispatcher;
foreach (EndpointDispatcher endpointDispatch in channelDispatcher.Endpoints)
{
endpointDispatch.DispatchRuntime.MessageInspectors.Add(new HttpContextPrincipalInspector());
}
}
// AddBindingParameters, ApplyClientBehavior, and Validate implementations
// can be empty - they don't do anything.
}
public class HttpContextPrincipalElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(HttpContextPrincipalBehavior); }
}
protected override object CreateBehavior()
{
return new HttpContextPrincipalBehavior();
}
}