身份验证WCF REST服务
我正在使用身份验证WCF REST服务,wcf,authentication,rest,Wcf,Authentication,Rest,我正在使用WebScriptServiceHostFactory构建一个WCF rest服务,以支持POX和Json消息格式,并实现了自定义属性来处理操作的授权。我想将状态代码作为响应发送,并结束对未授权请求的请求,因此我将从自定义属性引发异常,并在IErrorHandler中进行处理。但我无法将状态代码发送到客户端 我得到的HTTP状态码是202(“已接受”)而不是401(“未经授权”)。 下面的代码有什么错误吗 [ServiceContract] public interface Irest
WebScriptServiceHostFactory
构建一个WCF rest服务,以支持POX和Json消息格式,并实现了自定义属性来处理操作的授权。我想将状态代码作为响应发送,并结束对未授权请求的请求,因此我将从自定义属性引发异常,并在IErrorHandler
中进行处理。但我无法将状态代码发送到客户端
我得到的HTTP状态码是202(“已接受”)而不是401(“未经授权”)。
下面的代码有什么错误吗
[ServiceContract]
public interface Irestservice
{
[OperationContract]
[WebGet]
bool signin(string username, string password);
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true,
InstanceContextMode = InstanceContextMode.PerCall),
AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class restservice : Irestservice
{
[Authorization]
public bool signin(string username, string password)
{
return true;
}
}
public class AuthorizationAttribute : Attribute, IOperationBehavior,
IParameterInspector
{
public void ApplyDispatchBehavior(
OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
dispatchOperation.ParameterInspectors.Add(this);
}
public void AfterCall(string operationName, object[] outputs,
object returnValue, object correlationState)
{
}
public object BeforeCall(string operationName, object[] inputs)
{
string publicKey = WebOperationContext.Current
.IncomingRequest.Headers["Authorization"];
bool flag = AuthorizationHelper.CheckPartnerAuthorization( publicKey);
if (!flag)
{
WebOperationContext.Current.OutgoingResponse.StatusCode =
HttpStatusCode.Unauthorized;
throw new LicensingException("PartnerUnauthorized");
}
return null;
}
}
public class LicensingBehavior : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in
serviceHostBase.ChannelDispatchers)
{
RestErrorHandler newHandler = new RestErrorHandler();
channelDispatcher.ErrorHandlers.Add(newHandler);
}
}
}
class AppServiceHostFactory : WebScriptServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType,
Uri[] baseAddresses)
{
ServiceHost serviceHost =
base.CreateServiceHost(serviceType, baseAddresses);
serviceHost.Description.Behaviors.Add(new LicensingBehavior());
return serviceHost;
}
}
public class RestErrorHandler:IErrorHandler
{
#region IErrorHandler Members
public bool HandleError(Exception error)
{
return error is LicensingException;
}
public void ProvideFault(Exception error, MessageVersion version,
ref Message fault)
{
LicensingException licensingException = error as LicensingException;
if (licensingException != null)
{
fault = Message.CreateMessage(version, null,
new ValidationErrorBodyWriter(licensingException));
HttpResponseMessageProperty prop =
new HttpResponseMessageProperty();
prop.StatusCode = HttpStatusCode.Unauthorized;
prop.Headers[HttpResponseHeader.ContentType] =
"application/json; charset=utf-8";
fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
fault.Properties.Add(WebBodyFormatMessageProperty.Name,
new WebBodyFormatMessageProperty(WebContentFormat.Json));
}
}
class ValidationErrorBodyWriter : BodyWriter
{
private LicensingException licensingException;
Encoding utf8Encoding = new UTF8Encoding(false);
public ValidationErrorBodyWriter(LicensingException exception)
: base(true)
{
this.licensingException = exception;
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
writer.WriteStartElement("root");
writer.WriteAttributeString("type", "object");
writer.WriteStartElement("ErrorMessage");
writer.WriteAttributeString("type", "string");
writer.WriteString(this.licensingException.Message);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
}
您确定IErrorHandler接收到的错误实际上是授权异常吗?查看此项以确保正确实施了ProviderDefault方法。我使用的是factory和serice配置。因此,服务行为被工厂的行为所掩盖。因此,工厂和服务配置不应一起使用。请尝试在RestErrorHandler.ProviderDefault内执行此操作:
var response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = HttpStatusCode.Unauthorized;