Dyl*_*lan 6 c# security rest mobile wcf
我在WCF 4.0中实现了很多RESTful(GET和POST)方法.所有这些都通过SSL工作.
一些方法的示例:
[OperationContract]
[WebInvoke(UriTemplate = "Login?", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
LoginResponse Login(LoginRequest request);
[OperationContract]
[WebInvoke(UriTemplate = "UpdateDetails?", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
UpdateUserDetailResponse UpdateDetails(UpdateUserDetailRequest request);
[OperationContract]
[WebInvoke(UriTemplate = "GetDetails?", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
UserDetailResponse GetDetails(UserDetailRequest request);
Run Code Online (Sandbox Code Playgroud)
我查看了很多博客和论坛,但仍然无法找到符合我要求的内容.我需要对某些方法实现基本身份验证,但不是全部.如果你看一下上面的例子,我需要为UpdateDetails和GetDetails方法发送用户名和密码,而不是Login方法.然后,对数据库验证用户名和密码.可以这样做吗?
作为旁注:这些REST方法由许多不同的移动设备调用.
我查看了以下站点,它们都通过REST实现基本身份验证,但它们涵盖了上面提到的所有方法.
有可能做我想做的事吗?
我创建了一个 BasicAuthenticationInvoker 类,您可以将其归因于您想要验证的方法,如下所示:
[OperationContract]
[BasicAuthenticationInvoker] // this is the auth attribute!
[WebInvoke(UriTemplate = "QuickQuote?", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
QuickQuoteResponse QuickQuote(QuickQuoteRequest request);
Run Code Online (Sandbox Code Playgroud)
实际的类如下所示:
public class BasicAuthenticationInvoker : Attribute, IOperationBehavior, IOperationInvoker
{
#region Private Fields
private IOperationInvoker _invoker;
#endregion
#region IOperationBehavior Members
public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{
_invoker = dispatchOperation.Invoker;
dispatchOperation.Invoker = this;
}
public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{
}
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{
}
public void Validate(OperationDescription operationDescription)
{
}
#endregion
#region IOperationInvoker Members
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
if (Authenticate("Client Name here"))
return _invoker.Invoke(instance, inputs, out outputs);
else
{
outputs = null;
return null;
}
}
public object[] AllocateInputs()
{
return _invoker.AllocateInputs();
}
public IAsyncResult InvokeBegin(object instance, object[] inputs,
AsyncCallback callback, object state)
{
throw new NotSupportedException();
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
throw new NotSupportedException();
}
public bool IsSynchronous
{
get
{
return true;
}
}
#endregion
private bool Authenticate(string realm)
{
string[] credentials = GetCredentials(WebOperationContext.Current.IncomingRequest.Headers);
if (credentials != null && credentials.Length == 2)
{
// do auth here
var username = credentials[0];
var password = credentials[1];
// validate the username and password against whatever auth logic you have
return true; // if successful
}
WebOperationContext.Current.OutgoingResponse.Headers["WWW-Authenticate"] = string.Format("Basic realm=\"{0}\"", realm);
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized;
return false;
}
private string[] GetCredentials(WebHeaderCollection headers)
{
string credentials = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if (credentials != null)
credentials = credentials.Trim();
if (!string.IsNullOrEmpty(credentials))
{
try
{
string[] credentialParts = credentials.Split(new[] {' '});
if (credentialParts.Length == 2 && credentialParts[0].Equals("basic", StringComparison.OrdinalIgnoreCase))
{
credentials = Encoding.ASCII.GetString(Convert.FromBase64String(credentialParts[1]));
credentialParts = credentials.Split(new[] {':'});
if (credentialParts.Length == 2)
return credentialParts;
}
}
catch
{
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3067 次 |
最近记录: |