次のように、WCF WebAPI プロジェクトのカスタム OperationHandler を作成しました。
public class AuthenticationOperationHandler : HttpOperationHandlerFactory
{
protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
{
var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation);
if (operation.InputParameters.Where(p => p.Name.ToLower() == "username").Any() &&
operation.InputParameters.Where(p => p.Name.ToLower() == "password").Any())
{
baseHandlers.Add(new AuthenticateRequestHandler(string.Format("{0}:{1}", operation.InputParameters.Where(p => p.Name == "username").First ().Name, operation.InputParameters.Where(p => p.Name == "password").First().Name)));
}
else
{
throw new WebFaultException(HttpStatusCode.Forbidden);
}
return baseHandlers;
}
}
パイプラインに追加されるこのカスタム RequestHandler と同様に:
public class AuthenticateRequestHandler : HttpOperationHandler<HttpRequestMessage, string>
{
public AuthenticateRequestHandler(string outputParameterName)
: base(outputParameterName)
{
}
public override string OnHandle(HttpRequestMessage input)
{
var stringValue = input.Content.ReadAsString();
var username = stringValue.Split(':')[0];
var password = stringValue.Split(':')[1];
var isAuthenticated = ((BocaMembershipProvider)Membership.Provider).ValidateUser(username, password);
if (!isAuthenticated)
{
throw new WebFaultException(HttpStatusCode.Forbidden);
}
return stringValue;
}
}
これは私のAPI実装です:
[ServiceContract]
public class CompanyService
{
[WebInvoke(UriTemplate = "", Method = "POST")]
public bool Post(string username, string password)
{
return true;
}
}
Global.asax ファイルの私の構成は
public static void RegisterRoutes(RouteCollection routes)
{
var config = HttpHostConfiguration.Create().SetOperationHandlerFactory(new AuthenticationOperationHandler());
routes.MapServiceRoute<AuthenticationService>("login", config);
routes.MapServiceRoute<CompanyService>("companies", config);
}
/companys に POST リクエストを送信しようとすると、次のエラー メッセージが表示されます。
HttpOperationHandlerFactory は、サービス操作「Post」の要求メッセージ コンテンツに関連付ける必要がある入力パラメーターを特定できません。操作が要求メッセージのコンテンツを想定していない場合は、操作で HTTP GET メソッドを使用します。それ以外の場合は、1 つの入力パラメーターの IsContentParameter プロパティが「True」に設定されているか、HttpContent、ObjectContent
1, HttpRequestMessage or HttpRequestMessage
1 のいずれかに割り当て可能なタイプであることを確認してください。
この行で:
var baseHandlers = base.OnCreateRequestHandlers(endpoint, operation);
これが発生する理由と、ユーザーがすべてのリクエストでユーザー名/パスワードパラメーターを強制的に送信し、後でメンバーシップ API に対して検証するためにこれを修正する方法はありますか?