0

簡単なユーザー認証機能を作ろうとしているのですが、うまくいきません。ここに私が取り組んでいるコードがあります:

public class LoginController : ApiController
{
    private void SetPrincipal(IPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }
    }

    public bool Login(string token)
    {                       
        //Check token
        if (.....) 
        {
            //Authenticate user
            var identity = new GenericIdentity("Test user");
            SetPrincipal(new GenericPrincipal(identity, new string[]{"Test role"}));
        }
    }

    [Authorize]
    public string TestFun()
    {
        return "Hello " + User.Identity.Name;       
    }
}

そのため、最初にメソッドを呼び出そうとするとTestFun()、エラー コード 401 が返されます。ただし、メソッドを呼び出すとLogin()、ユーザーの資格情報が何らかの形で保存されるはずですが、ここで迷子になり、機能しません。

TestFun()Login()最初に呼び出しても、常にエラー コード 401 が返されます。関数に入れようとするとreturn "Hello " + User.Identity.Name;Login()正しいユーザー名が返されますがTestFun()、ユーザーは利用できません。

Sessions と FormsAuthentication を使用してみましたが、この非常に単純な例でも機能しません。

誰かが私に何が欠けているか教えてもらえますか?

ありがとう!

4

2 に答える 2

0

同じ問題が発生しました。はい、他のアクションを使用するためにそのプリンシパルをどこかに保存する必要があることに同意しました。そのため、 SetPrincipal 関数に追加しました

HttpContext.Current.Session["user"] = HttpContext.Current.User;

さて、問題は他のアクションのためにそれを取り戻す方法です。私の頭に浮かぶアイデアのポップアップは、AuthorizeAttribute を拡張し、IsAuthrized 関数をオーバーライドすることです。最初にセッションを読み取り、セッションが見つかった場合は true を返し、そうでない場合はfalse を返します。

namespace BinZ
{
    public class MyAuthorizeAttribute:AuthorizeAttribute
    {        

        protected override bool IsAuthorized(HttpActionContext actionContext) {            
            HttpContext.Current.User = HttpContext.Current.Session["user"] as IPrincipal;
            return HttpContext.Current.User != null;
        }
    }
}

WebApi コントローラーで [Authorize] を [MyAuthorizeAttribute] に置き換えることを忘れないでください。

それは私にとって非常にうまく機能します。

乾杯

于 2015-02-28T22:02:20.520 に答える
0

Login メソッドは、現在のリクエストに対してのみプリンシパルを設定します。リクエストが完了した直後に、サーバーが他のユーザーの他のリクエストを処理できるように、プリンシパル コンテキストが消去されます。新しいリクエストが来ると、サーバーの観点から何年も後に、プリンシパル コンテキストは存在しなくなり、何も復元されない場合、リクエストは認証されていません。

これを修正するには、ログイン メソッドからクライアントに何かを返す必要があります。bool だけでなく、むしろ認証トークンです。クライアントがさらなるリクエストを認証するために使用できるもの。

それは何でもかまいません。フォーム Cookie は、クライアントが後続の要求に追加することを覚えている限り問題ありません。もう 1 つの一般的な方法は、カスタム認証トークンをクライアントに返し、クライアントによってカスタム認証ヘッダーに追加されることです。また、フォーム Cookie はフォーム認証モジュールによって処理されるため、カスタム ヘッダーにはカスタム mvc 認証フィルターまたはカスタム asp.net 認証モジュールが必要です。これにより、トークンが読み取られ、ID が抽出され、要求が実行される直前に復元されます。

独自のトークン インフラストラクチャを焼きたくない場合は、OAuth2 トークンもお勧めします。この認証方法やその他の認証方法について、わかりやすい例が記載された素晴らしい本があります。

http://www.amazon.com/Pro-ASP-NET-Web-API-Security/dp/1430257822/ref=sr_1_1?ie=UTF8&sr=8-1&keywords=web+api+security

于 2013-11-03T21:44:07.683 に答える