2012-10-22 53 views
13

免責事項:私はMVC4 + Web API + Webサービスの一般的な+ JQueryを初めて使用していると言います。私は間違った角度でこれを攻撃しているかもしれません。ASP.NET Web APIを使用した基本認証とフォーム認証

私は、Web MVC App + Web APIを.NET用のC#でAzureにデプロイしようとしています。ウェブAPIはモバイルクライアント(iOS、RestKitを使用)によって使用されます。

Web MVC Appは比較的シンプルです。フォーム認証をSimpleMembershipに使用したいと思います。

JQuery(Knockout)スクリプトのWeb APIメソッドを使用して、Webページの一部を埋めます。したがって、JQueryはフォーム認証で認証された同一のIDを使用することを期待しています。

しかし、Web Apiはモバイルクライアントから直接呼び出すことができます。フォーム認証なし。

私たちはThinktecture Identity Model(http://nuget.org/packages/Thinktecture.IdentityModelhttps://github.com/thinktecture/Thinktecture.IdentityModel.40)を見てきました。 BasicAuthハンドラとAcessKeyハンドラをconfigに追加して動作させます(下記のコードを参照)。

認証されずにwebapiにアクセスしようとすると、ブラウザは基本認証ダイアログを表示し、期待どおりに動作します。

「問題」は、フォーム認証を使用して既にログインしていて、Web APIメソッドを呼び出そうとすると、基本認証ダイアログが表示されます。言い換えれば、Thinktecture IdentityModelはフォーム認証を完全に無視するようです。

私の質問は以下のとおりです。

  1. は私の期待は正しいですか?一度フォーム認証を済ませたら、JQueryスクリプトなどが同じブラウザユーザーセッションからWeb APIにアクセスできるように何もしないでください。
  2. どうすれば修正できますか?
  3. 私の期待が正しくない場合。これはどうやって動くのだろう?つまり、JQueryスクリプトを認証するにはどうしたらいいですか?

Stackoverflowにも同様の質問がたくさんあることは知っていますが、私は正直言ってたくさん見たことがありますが、見たビデオなどは分かりませんが、技術。

私は助けていただきありがとうございます。ありがとう。

public static AuthenticationConfiguration CreateConfiguration() 
{ 
var config = new AuthenticationConfiguration 
     { 
      DefaultAuthenticationScheme = "Basic", 
      EnableSessionToken = true, 
      SetNoRedirectMarker = true 
     };    

config.AddBasicAuthentication((userName, password) => userName == password, retainPassword: false); 
config.AddAccessKey(token => 
     { 
      if (ObfuscatingComparer.IsEqual(token, "accesskey123")) 
      { 
       return Principal.Create("Custom", 
        new Claim("customerid", "123"), 
        new Claim("email", "[email protected]")); 
      } 

      return null; 
     }, AuthenticationOptions.ForQueryString("key")); 

答えて

6

これは私が先に考え出したこの問題の解決策です。

注:このソリューションはThinktectureアイデンティティモデルを必要としません。

私は委任ハンドラである抽象的なBasicAuthenticationHandlerクラスを持っています。このハンドラは、最新の安定版WebAPIDoodle NuGet packageをインストールすることで取得できます。

リクエストがすでに認証されている場合(フォームauthなど)、この基本認証ハンドラにヒントを与えて認証プロセスを抑制することができます。あなたが登録する必要がカスタムハンドラは以下のように次のようになります。最後のステップとして

public class MyApplicationAuthHandler : BasicAuthenticationHandler { 

    public MyApplicationAuthHandler() 
     : base(suppressIfAlreadyAuthenticated: true) { } 

    protected override IPrincipal AuthenticateUser(
     HttpRequestMessage request, 
     string username, 
     string password, 
     CancellationToken cancellationToken) { 

     //this method will be called only if the request 
     //is not authanticated. 

     //If you are using forms auth, this won't be called 
     //as you will be authed by the forms auth bofore you hit here 
     //and Thread.CurrentPrincipal would be populated. 

     //If you aren't authed: 
     //Do you auth here and send back an IPrincipal 
     //instance as I do below. 

     var membershipService = (IMembershipService)request 
      .GetDependencyScope() 
      .GetService(typeof(IMembershipService)); 

     var validUserCtx = membershipService 
      .ValidateUser(username, password); 

     return validUserCtx.Principal; 
    } 

    protected override void HandleUnauthenticatedRequest(UnauthenticatedRequestContext context) { 

     // Do nothing here. The Autharization 
     // will be handled by the AuthorizeAttribute. 
    } 
} 

を、あなたは、特定のロールの認可を与えるためにあなたのコントローラやアクションメソッドにSystem.Web.Http.AuthorizeAttribute(ないSystem.Web.Mvc.AuthorizeAttribute)を適用する必要がありますし、ユーザー。

私はこれがあなたの問題の解決に役立つことを願っています。

+0

こんにちは、これは良いです。しかし、 "IMembershipService"インターフェースはどこから来ていますか? (これはWebAPIDoongleまたは標準の.NET4 MVCの一部ではないようです)。クラスが機能することに注意してください。同じクラスでAPIキーを処理してもらいたいと思いますが、その機能を追加できると思います。私の主な問題は、「WebSecurity」クラスを使用してデータベースに対してユーザーを検証し、プリンシパルを返す方法です(私はWebSecurity.Loginを実行できますが、それはちょっと面倒です)。 – rufo

+0

BTW:ブラウザ(Chrome)からテストするときに、ユーザーがログに記録されていない場合、ブラウザが基本認証を提供することはありません。それは私のモバイルクライアントにとっては必要ではありませんが、テストするのに便利です。私もそれをチェックします。 – rufo

+0

@rufo IMembershipServiceは私自身の実装です。私はアイデアを得るためにそこに置いた。それをあなた自身のimplで置き換えることができます。 – tugberk

関連する問題