web-dev-qa-db-ja.com

このリクエストの承認は拒否されました。常に

すでにMVC webApiプロジェクトを作成しましたが、認証と承認を使用したいと思います。私はすでにこのセキュリティを実装していると思いますが、何らかの理由で何かがうまくいかず、資格情報を書き込んでwebApiメソッドを呼び出そうとすると、「このリクエストに対して認証が拒否されました」というメッセージが表示されます。

これは私が実装したコードです。

WebApiConfig:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

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

        config.Filters.Add(new AuthorizeAttribute());
    }

ルーティング構成:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Routing", action = "LogIn", id = UrlParameter.Optional }
        );
    }

コントローラ:

public class RoutingController : Controller
{
    //
    // GET: /Routing/
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Projects()
    {
        return View();
    }

    public ActionResult Users()
    {
        return View();
    }

    public ActionResult LogIn()
    {
        return View();
    }

    [HttpPost]
    public JsonResult LogInPost(string userName, string password)
    {
        User user = new User();
        RoleByUser rByU = new RoleByUser();
        password = UserController.EncriptPassword(password);
        string url = string.Empty;
        var checkUser = user.Get(userName);
        var userExists = (from userInList in checkUser where userInList.UserName == userName && userInList.Password == password select userInList).FirstOrDefault();
        if(userExists!= null)
        {
            var roles = (from roleByUser in userExists.listOfRole select roleByUser.RoleName.Trim()).ToArray();
            IPrincipal principal = new GenericPrincipal(
            new GenericIdentity(userExists.UserName), roles);
            SetPrincipal(principal);
            url = "Routing/Users";
        }
        return Json(url);
    }

    private void SetPrincipal(IPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (System.Web.HttpContext.Current != null)
        {
            System.Web.HttpContext.Current.User = principal;
        }
    }

}

HTML:

<link href="~/css/Style.css" rel="stylesheet" type="text/css" />

<div class="container">
    <div class="card card-container">
        <img id="STK" class="profile-img-card" src="Images/Softtek.png" />
        <p id="profile-name" class="profile-name-card"></p>
        <form class="form-signin">
            <span id="reauth-email" class="reauth-email"></span>
            <input type="text" id="txtUserName" class="form-control" placeholder="Email address" required autofocus />
            <input type="password" id="txtPassword" class="form-control" placeholder="Password" required />
            <div id="remember" class="checkbox">
                <label>
                    <input type="checkbox" value="remember-me" /> Remember me
                </label>
            </div>
            @*<button id="btnLogIn" class="btn btn-lg btn-primary btn-block btn-signin"  >Sing In</button>*@
        </form><!-- /form -->
        <button id="btnLogIn" class="btn btn-lg btn-primary">Sing In</button>
        <a href="#" class="forgot-password">
            Forgot the password?
        </a>
    </div><!-- /card-container -->
</div><!-- /container -->

JS:

$(document).ready(function(){$( '#btnLogIn')。click(logIn);});

function logIn() {
    $.ajax({
        type: "POST",
        url: "http://localhost:21294/Routing/LogInPost",
        dataType: "json",
        data: { userName: $('#txtUserName').val(), password: $('#txtPassword').val() },
        success: function (data) {
            if(data!= "" && data!= undefined && data!= null)
                window.location.href = data;
        },
        error: function (err, e, error) {
            toastr.error('Error')
        }
    });
8
user3442776

コントローラのLogInPost[AllowAnonymous]属性を追加する必要があります

AuthorizeAttributeをフィルターに追加すると、コントローラーは、ログインに使用されるものを含むすべてのアクションに対して、デフォルトで承認が必要であるとコントローラーに想定させます。

12
Jonathon Chase

Windows認証を行っていますか? 「アクセスが拒否されました」というエラーが表示されますか?

時々IISEXpressとIISはいくつかのトリックを実行し、ローカルiis(inetmgr)でサイトをホストしていることを克服するために、認証(該当する場合はWindows)を有効にして実行します。

追伸すべてのマシンにIISサーバーがデフォルトでインストールされているわけではないため、inetmgrが機能しない場合は、コントロールパネルからインストールする必要があります-> Windowsの機能->すべての機能を選択IISおよびASP .NET

これがお役に立てば幸いです。

3
dotNetAuthor

IISがホストするWeb APIから自己ホストするWeb APIに切り替えたため、同じ問題が発生し始めたため、質問が見つかりました。

私の場合、問題はThread.CurrentPrincipalの初期化方法が原因でした。背景:

  1. カスタム認証ハンドラー(DelegationHandlerから継承)を使用しています
  2. このハンドラーでは、SendAsyncメソッドをオーバーライドして、カスタムユーザー検証を行います。
  3. 検証が成功した場合は、ClaimsPrincipalクラスのインスタンスを作成して、現在のユーザーに関するいくつかのクレームを含めます。

以前は、パイプライン内の残りのメッセージハンドラーにメッセージを渡す前に、このClaimsPrincipalインスタンスをThread.CurrentPrincipalに割り当てていました。ただし、私にとっての解決策は、SendAsyncに渡されるHttpRequestMessageインスタンスに属するHttpRequestContextインスタンスの代わりにPrincipalメンバーを使用することでした。したがって(F#で)、

override this.SendAsync(request : HttpRequestMessage, cancellationToken : CancellationToken) =
  // Do some user validation here first
  // .. then setup the claims (method details omitted) 
  let principal = BuildClaimsPrincipal

  // Assign to Principal on HttpRequestContext
  let requestContext = request.GetRequestContext
  requestContext.Principal <- principal

  // Rest of method omitted...

これが何らかの形であなたを助けることができることを願っています。

2
1MuddyDog