は、以下のWCFの宣言を見てみましょう。
[BasicHttpAuthorization(RequireSsl = true)]
[WebGet(UriTemplate = "")]
public IEnumerable Get()
{
.....
}
のでBasicHttpAuthorization
今、あなたはHttpOperationHandlerの実装を見てとることができAttribute
[AttributeUsage(AttributeTargets.Method)]
public class BasicHttpAuthorizationAttribute : Attribute
{
bool requireSsl = true;
public bool RequireSsl
{
get { return requireSsl; }
set { requireSsl = value; }
}
}
を実装しています。
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;
}
}
}
これまでに何を試しましたか? – khlr