我想在属性类中获取端点方法请求上下文。
所以,如果我有这个端点
[Auth]
[WebInvoke(UriTemplate ="/post",
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
public string CreatePost(var data)
然后在课堂上
public class Auth : Attribute
{
public bool IsAuthorised()
{
// get the request then add something to the endpoint context
答案 0 :(得分:1)
请看下面的WCF声明。
[BasicHttpAuthorization(RequireSsl = true)]
[WebGet(UriTemplate = "")]
public IEnumerable Get()
{
.....
}
因此BasicHttpAuthorization
实施Attribute
[AttributeUsage(AttributeTargets.Method)]
public class BasicHttpAuthorizationAttribute : Attribute
{
bool requireSsl = true;
public bool RequireSsl
{
get { return requireSsl; }
set { requireSsl = value; }
}
}
现在您可以查看HttpOperationHandler的实现。
1)如果用户尚未通过身份验证或提供错误的凭据,我们会在OnHandle
方法中返回HttpResponseException。我们将状态代码设置为401.这会创建功能,浏览器会要求输入用户名/密码,然后自动重新发送请求。
2)在ParseAuthHeader
中,我们从请求中获取用户名和密码。然后,您可以以自己的方式使用此信息。例如,使用您自己的自定义成员资格提供程序。
3)如果用户可以访问此方法,则创建GenericPrincipal
并将其分配给HttpContext.Current.User
。
public class BasicHttpAuthorizationOperationHandler : HttpOperationHandler
{
BasicHttpAuthorizationAttribute basicHttpAuthorizationAttribute;
public BasicHttpAuthorizationOperationHandler(BasicHttpAuthorizationAttribute authorizeAttribute)
: base("response")
{
basicHttpAuthorizationAttribute = authorizeAttribute;
}
protected override HttpRequestMessage OnHandle(HttpRequestMessage input)
{
if (Authenticate(input))
{
return input;
}
else
{
var challengeMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
challengeMessage.Headers.Add("WWW-Authenticate", "Basic");
throw new HttpResponseException(challengeMessage);
}
}
private bool Authenticate(HttpRequestMessage input)
{
if (basicHttpAuthorizationAttribute.RequireSsl && !HttpContext.Current.Request.IsSecureConnection && !HttpContext.Current.Request.IsLocal) return false;
if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization")) return false;
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
IPrincipal principal;
if (TryGetPrincipal(authHeader, out principal))
{
HttpContext.Current.User = principal;
return true;
}
return false;
}
private bool TryGetPrincipal(string authHeader, out IPrincipal principal)
{
var creds = ParseAuthHeader(authHeader);
if (creds != null)
{
if (TryGetPrincipal(creds[0], creds[1], out principal)) return true;
}
principal = null;
return false;
}
private string[] ParseAuthHeader(string authHeader)
{
// Check this is a Basic Auth header
if (authHeader == null || authHeader.Length == 0 || !authHeader.StartsWith("Basic")) return null;
// Pull out the Credentials with are seperated by ':' and Base64 encoded
string base64Credentials = authHeader.Substring(6);
string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(new char[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[0])) return null;
// Okay this is the credentials
return credentials;
}
private bool TryGetPrincipal(string userName, string password, out IPrincipal principal)
{
// this is the method that does the authentication
// you can replace this with whatever logic you'd use, but proper separation would put the
if (userName.Equals("test") && password.Equals("test"))
{
principal = new GenericPrincipal(new GenericIdentity(userName), new string[] {"Admin", "User"});
return true;
}
else
{
principal = null;
return false;
}
}
}