5

アップデート:

コードを に変更しましたFormsAuthentication.SetAuthCookie(_model.UserName, true);。1 つは MVC 用、もう 1 つは WebAPI 用です。MVC 構成で、私は定義します

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

両方のアプリケーションが同じドメインにあります。


更新: WebAPI で Cookie を使用する必要がありますか?


現在、フォーム認証と WebAPI プロジェクトを使用する MVC プロジェクトがあります。問題は、WebAPI プロジェクトで要求に関連付けられたユーザーを取得できないことです。これは可能だと思いましたか、それとも実装が間違っているのでしょうか?

注: テストとして WebAPI コントローラー メソッドに Cookie コードを入れましたが、本来あるべき場所ではありません。

MVC - ログイン要求を処理し、認証チケットを作成します。

// POST: /Account/Login
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel _model, string _returnUrl)
{
    if (ModelState.IsValid)
    {
        if (Membership.ValidateUser(_model.UserName, _model.Password))
        {
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(_model.UserName, true, 15);
            string encryptedTicket = FormsAuthentication.Encrypt(ticket);
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            Response.Cookies.Add(cookie);

            // set redirect
        }
    }

    // If we got this far, something failed, redisplay form
    return View(_model);
}

WebAPI - 更新リクエストを処理します

[AcceptVerbs("PUT")]
public HttpResponseMessage UpdateInfo(int _id, ExampleModel _model)
{
    try
    {
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            string encTicket = authCookie.Value;

            if (!String.IsNullOrEmpty(encTicket))
            {
                // decrypt the ticket if possible.
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);

                var userData = ticket.UserData;
            }
        }

        // do update
        return Request.CreateResponse(HttpStatusCode.OK, data, GlobalConfiguration.Configuration);
    }
    catch (Exception err)
    {
        m_logger.Error(err);
        throw;
    }
}
4

2 に答える 2

9

フォーム認証チケットを手動で作成する必要があるのはなぜですか? なんでこれしかできないの?

if (Membership.ValidateUser(_model.UserName, _model.Password))
{
    FormsAuthentication.SetAuthCookie(_model.UserName, true);

    // set redirect
}

タイムアウトを制御するには、web.config で次のように設定します。

<authentication mode="Forms">
    <forms timeout="15" />
</authentication>

これを行うと、Cookie をチェックしてユーザーの名前を取得する必要がなくなります。コントローラーのUser.Identity.Nameプロパティで自動的に設定する必要があります。これは MVCControllerApiControllerの両方で機能します。

また、MVC アプリケーションと WebAPI アプリケーションを Web サーバーの別のノード (または別のサーバー) でホストしている場合、MVC プロジェクトと WebAPI プロジェクトの両方のmachineKeyweb.config ファイルが同じである必要があります。これらも同じドメインにある必要がありますが、別々の web.config ファイルを持つ別々のアプリケーションである場合は、同じmachineKey値 ( decryptiondecryptionKeyvalidation、およびvalidationKey) を持っている必要があります。これらは、.ASPXAUTH Cookie の検証、暗号化、および復号化に必要な値です。

WebAPI で Cookie を使用する必要がありますか?

上記のパターンを使用する場合、少なくとも認証/承認のために、Cookie を手動で取得する必要はありません。Cookie は、メソッド、ヘッダー、応答コードなどとともに HTTP 仕様の一部です。WebAPI には理由があります。必要な場合は、それらを使用してください。それらが必要ない場合は、使用しないでください。

避けるべきことは、次のようにしてそれらを取得することです。

HttpCookie authCookie = HttpContext.Current.Request.Cookies["name"];

次のように、ApiController から Cookie を取得できます。

IEnumerable<CookieHeaderValue> cookies = this.Request.Headers.GetCookies("name");
if (cookies.Any())
{
    IEnumerable<CookieState> cookie = cookies.First().Cookie;
    if (cookie.Any())
    {
        string value = cookie.First().Value;
    }
}

アップデート

私は常にこの生成ツールを使用しています: http://aspnetresources.com/tools/machineKey

[キーの生成] ボタンをクリックして、結果のセクションを両方の web.config ファイル<machineKey ../>のセクションの下に貼り付けます。<system.web>

アップデート

web.config ファイルを表示するアクセス権を持つユーザーによっては、セキュリティ上の問題が発生する可能性があります。このようにソース管理リポジトリにチェックインすると、ソース コードにアクセスできる人なら誰でも検証キーと暗号化キーを見ることができます。

私がしていることは少し複雑ですが、これらの文字列を安全に保ちます。代わりにvalidationKeyとのencryptionKey値をに保存してから、構成ファイルのセクションをappSettings暗号化できます ( CloudConfigCryptoなどを使用)。これは、暗号化証明書の秘密鍵にアクセスできない人は、これらの値を読み取ることができないことを意味します。その後、このクラスを使用して、実行時に値を変更できます。ただし、これに関する詳細は、この質問の範囲外です。appSettingsMicrosoft.Web.Administration.ServerManagermachineKeyApplication_Start

別のオプションは、これらをソース管理から除外することですが、デプロイするたびに web.config を手動で更新する必要があります。

于 2013-04-23T12:41:10.950 に答える
0

名前空間のWebSecurityクラスを使用して、Web API および MVC アプリケーションと共にフォーム認証を使用する最も簡単な方法を見つけました。WebMatrix.WebDataユーザーアカウントの作成、ユーザーのログインとログアウト、パスワードのリセットまたは変更など、最も頻繁に使用される操作に非常に簡単にアクセスできます。また、セッション Cookie を自分で処理する必要はありません。

Web API と MVC アプリケーションの両方にフォーム認証を使用する必要がある、あなたと同様のセットアップで使用しました。

API の例

ログイン:

if(WebSecurity.Login(username, password))
{
    return Request.CreateErrorResponse(
        HttpStatusCode.Forbidden, "Invalid credentials");
}
else
{
    return Request.CreateResponse(HttpStatusCode.OK);
}

登録:

if(WebSecurity.UserExists(username))
{
    return Request.CreateErrorResponse(
        HttpStatusCode.BadRequest, "Username already exists");
}

WebSecurity.CreateUserAndAccount(username, password, data);

HttpResponseMessage response = Request.CreateResponse(
    HttpStatusCode.Created, yourUserObject);
    response.Headers.Location = new Uri(
        Url.Link("DefaultApi",
            new { controller = "users", id = WebSecurity.GetUserId(username) }));
return response;

MVC アプリケーションでも同じ呼び出しが機能します。

于 2013-04-23T13:17:43.407 に答える