aspnet webforms中的WCF服务抛出302 [英] WCF Service inside aspnet webforms throwing 302
问题描述
我在现有的 ASPNET webforms 站点中创建了一个 WCF 服务,然后我继续将 FormsAuthentication 添加到 aspnet 站点,在位置标记中添加了一个部分以允许匿名访问 .svc 文件,我可以浏览 WSDL文件没有问题,但是当我尝试调用该服务时,我收到 302,该服务已设置为使用 basicAuth.
I have created a WCF service inside an existing ASPNET webforms site, I then proceeded to add FormsAuthentication to the aspnet site, added a section in the location tag to allow anonymous access to the .svc file, I can browse through the WSDL file no issue, but when I try to call the service, I get a 302, the service is setup to use basicAuth.
我尝试添加一个 HttpModule 来拦截服务请求并返回适当的消息,但效果不佳.
I tried added a HttpModule to intercept the service request and return an appropriate message but that doesnt work as well.
这是服务文件夹中的 Webconfig.
Here is the Webconfig inside the service folder.
<?xml version="1.0"?>
<configuration>
<system.web>
<httpModules>
<add name="AuthRedirectHandler" type="Test.Modules.AuthRedirectHandler, Test" />
</httpModules>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="AuthRedirectHandler" type="Test.Modules.AuthRedirectHandler, Test" preCondition="managedHandler"/>
</modules>
</system.webServer>
</configuration>
HttpModule,添加了一些其他事件,但没有一个被命中
The HttpModule, addded a few other events but none get hit
public class AuthRedirectHandler : IHttpModule
{
public void Dispose()
{
//throw new NotImplementedException(); -- do nothing here
}
public void Init(HttpApplication context)
{
context.EndRequest += new EventHandler(context_EndRequest);
context.BeginRequest += Context_BeginRequest;
context.AuthenticateRequest += Context_AuthenticateRequest;
context.AuthorizeRequest += Context_AuthorizeRequest;
context.PreRequestHandlerExecute += Context_PreRequestHandlerExecute;
context.PostAuthorizeRequest += Context_PostAuthorizeRequest;
}
private void Context_PostAuthorizeRequest(object sender, EventArgs e)
{
int k = 0;
}
private void Context_PreRequestHandlerExecute(object sender, EventArgs e)
{
int k = 0;
}
private void Context_AuthorizeRequest(object sender, EventArgs e)
{
int k = 0;
}
private void Context_AuthenticateRequest(object sender, EventArgs e)
{
int k = 0;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
int k = 0;
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;
if (app != null &&
app.Response.StatusCode == 302)//302 Found
{
app.Response.ClearHeaders();
app.Response.ClearContent();
app.Response.StatusCode = 401;
}
}
当我检查 fiddler 请求时,我可以对服务执行正常的 HttpWebRequest,但是当我尝试调用一个方法时,我得到一个 302 响应,继续加载我的登录页面.
When I check under fiddler request, I can do a normal HttpWebRequest to the service, but when I try to call a method, I get a 302 response that the proceeds to load my login page.
推荐答案
这适用于一些可能需要参考如何解决问题的人,我最终选择了这条路线
This is for some that might need reference on how to fix the issue, I ended up going down this route
- 删除 .svc 文件的任何形式的安全性
- 创建一个 messageInspector 以将 Basic Auth 标头添加到 WCF(Client)
- 将 messageInspector 添加到 ServiceBehavior
- 将 serviceBehavior 添加到您的服务端点行为
- 在服务中,创建一个 ServiceAuthorizationManager
- 将 ServiceAuthorizationManager 添加到您的服务的 web.config
1.删除任何安全
<location path="Services/UpdaterService.svc">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
2.创建一个messageInspector,将Basic Auth header 添加到WCF(Client)
public class ServiceMessageServiceCredentialsInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
HttpRequestMessageProperty requestMessageProperty = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
requestMessageProperty.Headers[HttpRequestHeader.Authorization] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}"));
return null;
}
}
3.将 messageInspector 添加到 ServiceBehavior
public class ServiceInterceptionBehavior : BehaviorExtensionElement,IEndpointBehavior
{
public override System.Type BehaviorType
{
get { return typeof(ServiceInterceptionBehavior); }
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new ServiceMessageServiceCredentialsInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
protected override object CreateBehavior()
{
throw new NotImplementedException();
}
}
4.将 serviceBehavior 添加到您的服务端点行为
EndpointAddress address = new
EndpointAddress("http://localhost:14138/Services/Service.svc");
ChannelFactory<IService> myChannelFactory = new
ChannelFactory<IUpdaterService>(defaultBinding, address);
myChannelFactory.Endpoint.EndpointBehaviors.Add(new ServiceInterceptionBehavior());
var address2 = myChannelFactory.CreateChannel(address);
5.在 Service 中,创建一个 ServiceAuthorizationManager
public class ServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
//Extract the Athorizationm Header,a nd parse out the credentials converting to base64 string
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if ((authHeader != null) && (authHeader != string.Empty))
{
var svcCredentials = System.Text.ASCIIEncoding.ASCII
.GetString(Convert.FromBase64String(authHeader.Substring(6)))
.Split(':');
return DefaultPasswordValidator.ValidateCridentials(svcCredentials[0], svcCredentials[1]);
}
else
{
//No authorization header was provided, so challenge the client to provide before proceeding:
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"UpdaterService\"");
//Throw an exception with the associated HTTP status code equivalent to HTTP status 401
throw new FaultException("Please provide a username and password");
}
}
6.将 ServiceAuthorizationManager 添加到您的服务的 web.config
<serviceAuthorization serviceAuthorizationManagerType="ServiceAuthorizationManager, AssemblyName, Version=2.0.0.1, Culture=neutral, PublicKeyToken=null" />
<serviceAuthenticationManager serviceAuthenticationManagerType="ServiceAuthenticationManager, AssemblyName"
authenticationSchemes="Basic" />
这篇关于aspnet webforms中的WCF服务抛出302的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!