1

承認と認証はかなり新しいので、重要なステップを見逃している可能性があります...多数のリファレンス、ガイド、チュートリアルを見ているだけです。

WebApiConfig で何かをする必要があるかもしれません。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

または、おそらく私の Global.asax で:

public class WebApiApplication : System.Web.HttpApplication
{
    private const string RootDocument = "/index.html";
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // Stuff to redirect to index.html unless it's an api url
    }
}

これは、Angular 2 フロントエンドを備えた .NET Framework 4.5.2 をターゲットとする ASP.Net Web API プロジェクトであり、フロントエンドで手動で何もしません。おそらくそれを行う必要がありますか? ブラウザのローカル ストレージ、セッション ストレージ、および Cookie がすべて空です。

私がアクセスしている SQL Server には、ロールと userId を返す非常に単純なユーザー ログオン メソッドがあり、これをリポジトリで呼び出します。

    public static DbUser Logon(AuthUser user)
    {
        var parameters = new List<SqlParameter>();
        {
            // Add parameters, get the DbUser (contains role and userId), and return the DbUser
        }
    }

ログオン フロントエンドは Angular 2 で構築され、次の API メソッドへの送信時にユーザー名とパスワードを使用して HttpPost 呼び出しを行い、ID とプリンシパルを作成し、Thread と HttpContext を設定します。

    // POST api/<controller>
    [HttpPost]
    public TokenUser Post(AuthUser user)
    {
        var dbUser = DBAccess.Repository.User.Logon(user);

        var identity = new ClaimsIdentity();
        identity.AddClaim(new Claim(ClaimTypes.Name, "CwRole"));
        identity.AddClaim(new Claim(ClaimTypes.Role, dbUser.AccessLevel));
        identity.AddClaim(new Claim(ClaimTypes.UserData, dbUser.ID.ToString()));

        var principal = new ClaimsPrincipal(identity);
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
            HttpContext.Current.User = principal;

        // Other stuff and a return statement =>
        // Note I'm not actually doing anything manually with the token on the front end
        // which may be why I'm not seeing it in the debugger's Resources tab...
    }

そのコードをステップ実行すると、Thread.CurrentPrincipal と HttpContext.Current.User の両方が設定されていることがはっきりとわかります。

しかし、アクションを [Authorize] 属性で装飾すると、ログインしているかどうかに関係なくアクセスできなくなります。

        // Works fine
        public IEnumerable<ItemGroup> Get()
        {
            return DBAccess.Repository.Item.GetItemGroups();
        }

        // Responds with 401 (Unauthorized) no matter what
        [Authorize]
        public IEnumerable<RequestItem> Get()
        {
            return DBAccess.Repository.Item.GetRequestItems();
        }

したがって、これらのメソッドを作成し、上記のログオンプロセスの後にブラウザーの URL を介してアクセスし、ステップスルーしましたが、ユーザーが実際に設定されていないことがわかりました (クレームはすべて空などです...)。

public class AuthController : ApiController
{
    public bool Get()
    {
        // Stepping through, looks like User.Identity is not even set...
        var authenticated = User.Identity.IsAuthenticated;
        return authenticated;
    }

    public bool Get(string role)
    {
        // As a matter of fact, User doesn't have any claims or anything...
        var user = User;
        return user != null && user.IsInRole(role);
    }
}

設定後にプリンシパルにアクセスできるようにするために、どのステップが欠けていますか? WebApi の組み込みの「ユーザー」メソッド以外でアクセスするか、構成に何かを設定するか、フロントエンドで手動で何かを行う必要がありますか?

4

2 に答える 2

1

クレーム認証を使用しているため、認証が成功するとトークンを受け取ります。したがって、後続/後続の Web Api 要求のトークンを永続化するには、次のいずれかの方法で永続化する必要があります

  1. 認証の詳細をCookieに設定する必要があります。これは、ブラウザによって後続のすべてのリクエストに自動的に追加されますOR
  2. 次の要求のために、ブラウザーのローカル ストレージにトークンを永続化できます。[認証のために] 要求ヘッダーにクレーム ベアラー トークンを追加する必要があります。

オプション1:

認証クッキーの設定

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), true, userData);
         string encTicket = FormsAuthentication.Encrypt(ticket);
         HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
         Response.Cookies.Add(faCookie);

後続のリクエストでの認証のための Cookie へのアクセス。

HttpCookie authCookie = Request.Cookies[
             FormsAuthentication.FormsCookieName];
    if(authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = 
               FormsAuthentication.Decrypt(authCookie.Value);
        // Create an Identity object
        //CustomIdentity implements System.Web.Security.IIdentity
        CustomIdentity id = GetUserIdentity(authTicket.Name);
        //CustomPrincipal implements System.Web.Security.IPrincipal
        CustomPrincipal newUser = new CustomPrincipal();
        Context.User = newUser;
    }

オプション 2:

トークンを取得してブラウザのローカル ストレージに保存できます。Authorize キーワードを使用して API にリクエストを行うときはいつでも、ベアラー トークンをリクエスト ヘッダーに追加していることを確認してください。

このようなもの

var authData = localStorageService.get('authorizationData');
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }

次の記事では、トークン ベースの認証について説明し、Angular JS のコード サンプルを示していますが、 http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp- をご覧ください。 net-web-api-and-identity-2/

ついに、

サーバー側での検証では、デフォルトの承認の代わりにカスタム承認を記述して、トークンを検証し、それに応じて ID を設定できます。

于 2016-08-07T21:03:25.483 に答える
0

OnAuthorizationイベントはパイプラインの非常に早い段階で発生します。任意のタイプがその後をActionFilter実行します。ご想像のとおり、認証コード (最初のスニペット) をアクション フィルター、またはOnAuthorizationイベント後に実行される場所に記述しました。

そのコードを、たとえば、このイベント ( in global.asax.cs)に転送することを検討する必要があります。

Application_PostAuthenticateRequest(Object sender, EventArgs e).

より洗練された方法は、カスタムを実装し、プリンシパルAuthorizeAttributeからユーザー情報を取得して設定することです。Request

于 2016-08-01T10:34:52.087 に答える