如何在WCF Restful Service中实现身份验证和授权
我正在尝试实现WCF休息服务的安全性,这些服务将通过网络暴露给消费者。 这是要求
授权服务和特定的API
服务应授权合作伙伴并检查合作伙伴是否有权访问所调用的API,并且我有多个合作伙伴调用这些安宁的API。
我如何以集中方式授权每个这些合作伙伴的API?
用户身份验证
我需要为用户执行验证才能执行添加,删除操作。
如何以集中方式对特定API的用户进行身份验证。
请看这里的Azure存储REST API安全文档,以获得有关MS如何围绕其API设计安全性的公平想法。
我看到的大多数REST API都使用基于API令牌的方法,这些令牌传递给每个请求以标识调用者。 也看看这个线程
我使用以下方法来实现其余服务的授权和身份验证。
使用实现属性的自定义属性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();
}
}
}
链接地址: http://www.djcxy.com/p/71355.html
上一篇: How to implement Authentication and Authorization in WCF Restful Service
下一篇: Should I pass Credentials via HTTP Header or Post body as JSON to REST Api?