身份验证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;