ServiceAuthorizationManager 中的授权 header 在第二次调用中为空
Authorization header in ServiceAuthorizationManager is null in second call
我有一个 WCF REST 服务,它接受 xml 数据作为输入和 returns 一些数据。为了实现基本身份验证,我使用 ServiceAuthorizationManager。 CheckAccessCore 方法自动调用两次。 CheckAccessCore中的第一次调用授权header是正确的,但是第二次调用授权header是空的。
ServiceAuthorizationManager CheckAccessCore 方法
protected override bool CheckAccessCore(OperationContext operationContext)
{
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
var credentials = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':');
var user = new
{
Name = credentials[0],
Password = credentials[1]
};
if (user.Name == "test" && user.Password == "pass")
{
return true;
}
else
{
return false;
}
}
else
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm =\"CreditData\"");
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
WCF Web.config
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization serviceAuthorizationManagerType="CreditDataService.Authorization.CreditDataAuthorizationManager, CreditDataService" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="CreditDataService.Services.CreditData" behaviorConfiguration="">
<endpoint name="REST" behaviorConfiguration="RestBehavior" binding="webHttpBinding" contract="CreditDataService.Contracts.ICreditData"/>
</service>
</services>
<protocolMapping>
<add binding="webHttpBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
客户
private void button4_Click(object sender, EventArgs e)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:33016/Services/CreditData.svc");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes("<Request><Firstname>John</Firstname><Lastname>Doe</Lastname><Pid>123456789</Pid></Request>");
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
request.Method = "POST";
string credentials = "test:pass";
string enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
string auth = string.Format("{0} {1}", "Basic", enc);
request.Headers[HttpRequestHeader.Authorization] = auth;
Stream reqStream = request.GetRequestStream();
reqStream.Write(bytes, 0, bytes.Length);
reqStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream respStream = response.GetResponseStream();
string respStr = new StreamReader(respStream).ReadToEnd();
MessageBox.Show(respStr);
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
MessageBox.Show(resp);
}
MessageBox.Show(ex.Message);
}
}
没有 ServiceAuthorizationManager 它工作正常。
问题出在网络服务方法的 UriTemplate 上。它是空的,当我调用服务时,发生了仅使用斜线重定向到相同的 url 的情况。例如当我向“http://localhost/myservice.svc" it was redirected to "http://localhost/myservice.svc/”发送请求时。这是第二个请求,而第二个请求恰好具有 Authorization header null。当我添加 UriTemplate 时问题解决了。
我有一个 WCF REST 服务,它接受 xml 数据作为输入和 returns 一些数据。为了实现基本身份验证,我使用 ServiceAuthorizationManager。 CheckAccessCore 方法自动调用两次。 CheckAccessCore中的第一次调用授权header是正确的,但是第二次调用授权header是空的。
ServiceAuthorizationManager CheckAccessCore 方法
protected override bool CheckAccessCore(OperationContext operationContext)
{
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
var credentials = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':');
var user = new
{
Name = credentials[0],
Password = credentials[1]
};
if (user.Name == "test" && user.Password == "pass")
{
return true;
}
else
{
return false;
}
}
else
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm =\"CreditData\"");
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
WCF Web.config
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Xml"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization serviceAuthorizationManagerType="CreditDataService.Authorization.CreditDataAuthorizationManager, CreditDataService" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="CreditDataService.Services.CreditData" behaviorConfiguration="">
<endpoint name="REST" behaviorConfiguration="RestBehavior" binding="webHttpBinding" contract="CreditDataService.Contracts.ICreditData"/>
</service>
</services>
<protocolMapping>
<add binding="webHttpBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
客户
private void button4_Click(object sender, EventArgs e)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:33016/Services/CreditData.svc");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes("<Request><Firstname>John</Firstname><Lastname>Doe</Lastname><Pid>123456789</Pid></Request>");
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
request.Method = "POST";
string credentials = "test:pass";
string enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
string auth = string.Format("{0} {1}", "Basic", enc);
request.Headers[HttpRequestHeader.Authorization] = auth;
Stream reqStream = request.GetRequestStream();
reqStream.Write(bytes, 0, bytes.Length);
reqStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream respStream = response.GetResponseStream();
string respStr = new StreamReader(respStream).ReadToEnd();
MessageBox.Show(respStr);
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
MessageBox.Show(resp);
}
MessageBox.Show(ex.Message);
}
}
没有 ServiceAuthorizationManager 它工作正常。
问题出在网络服务方法的 UriTemplate 上。它是空的,当我调用服务时,发生了仅使用斜线重定向到相同的 url 的情况。例如当我向“http://localhost/myservice.svc" it was redirected to "http://localhost/myservice.svc/”发送请求时。这是第二个请求,而第二个请求恰好具有 Authorization header null。当我添加 UriTemplate 时问题解决了。