How to implement authentication and authorization in the WCF Restful Service

I am trying to implement security for WCF Recreation Services, which will be displayed over the network for consumption. Here are the requirements

Service Permission and Specific API

The service should allow the partner and check if the partner has access to the API that is being called, and I have several partners calling these untrusted APIs.

How do I enable each of these partners APIs centrally?

User Authentication

I need to perform authentication for users in order to perform add, delete operations.

How can I centrally authenticate users for specific APIs.

+3
source share
3 answers

.

, , IOperationBehavior, IParameterInspector

.

public class AuthorizationAttribute : Attribute, IOperationBehavior, IParameterInspector
{

    public SLCE.Operations Operation { get; set; }

    public bool IsAuthenticationRequired { get; set; }

    #region IOperationBehavior Members

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
    {

    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {           
        dispatchOperation.ParameterInspectors.Add(this);
    }

    public void Validate(OperationDescription operationDescription)
    {

    }

    #endregion

    #region IParameterInspector Members

    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(this.Operation, publicKey);
        if (!flag)
        {   
            LicensingValidationHelper.ThrowLicensingException(HttpStatusCode.Unauthorized, SLCE.LicensingStatus.PartnerNotAuthorized.ToString());
        }
        else if(IsAuthenticationRequired)
        {
            string authenticationKey = WebOperationContext.Current.IncomingRequest.Headers["Authentication"];
            bool isAuthenticated = AuthorizationHelper.CheckUserAuthentication(authenticationKey);

            if (!isAuthenticated)
            {
                LicensingValidationHelper.ThrowLicensingException(HttpStatusCode.Unauthorized, SLCE.LicensingStatus.UserNotAuthorized.ToString());                  
            }
        }
        return null;
    }

    #endregion      

}

Beahavior .

public class LicensingBehavior : WebHttpBehavior
{

    protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        int errorHandlerCount = endpointDispatcher.ChannelDispatcher.ErrorHandlers.Count;
        base.AddServerErrorHandlers(endpoint, endpointDispatcher);
        IErrorHandler webHttpErrorHandler = endpointDispatcher.ChannelDispatcher.ErrorHandlers[errorHandlerCount];
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.RemoveAt(errorHandlerCount);
        RestErrorHandler newHandler = new RestErrorHandler(webHttpErrorHandler,DefaultOutgoingResponseFormat);
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(newHandler);
    }        

}

IErrorhandler , .

public class RestErrorHandler : IErrorHandler
{
    IErrorHandler _originalErrorHandler;
    WebMessageFormat _format;
    public RestErrorHandler(IErrorHandler originalErrorHandler,WebMessageFormat format)
    {
        this._originalErrorHandler = originalErrorHandler;
        this._format = format;
    }

    public bool HandleError(Exception error)
    {
        return error is WebProtocolException;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        WebProtocolException licensingException = error as WebProtocolException;
        if (licensingException != null)
        {

            fault = Message.CreateMessage(version, null, new ValidationErrorBodyWriter(licensingException));
            if (_format == WebMessageFormat.Json)
            {
                HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
                prop.StatusCode = licensingException.StatusCode;
                prop.Headers[HttpResponseHeader.ContentType] = "application/json; charset=utf-8";
                fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
                fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
            }
            else if(_format == WebMessageFormat.Xml)
            {
                HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
                prop.StatusCode = licensingException.StatusCode;
                prop.Headers[HttpResponseHeader.ContentType] = "application/xml; charset=utf-8";
                fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
                fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Xml));
            }
        }
        else
        {
            this._originalErrorHandler.ProvideFault(error, version, ref fault);
        }
    }

    class ValidationErrorBodyWriter : BodyWriter
    {
        private WebProtocolException validationException;
        Encoding utf8Encoding = new UTF8Encoding(false);

        public ValidationErrorBodyWriter(WebProtocolException validationException)
            : base(true)
        {
            this.validationException = validationException;
        }

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("root");
            writer.WriteAttributeString("type", "object");

            writer.WriteStartElement("StatusCode");
            writer.WriteAttributeString("type", "string");
            writer.WriteString(this.validationException.StatusCode.ToString());
            writer.WriteEndElement();

            writer.WriteStartElement("Description");
            writer.WriteAttributeString("type", "string");
            writer.WriteString(this.validationException.StatusDescription);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}
+1

Azure Storage REST api , , MS API.
API REST, , API, .

+1

All Articles