web-dev-qa-db-de.com

Für diese Anfrage wurde die Genehmigung abgelehnt. Immer

Ich habe bereits ein MVC-webApi-Projekt erstellt und möchte nun Authentifizierung und Autorisierung verwenden. Ich glaube, ich habe diese Sicherheit bereits implementiert, aber aus irgendeinem Grund geht etwas schief, wenn ich meine Anmeldeinformationen schreibe und versuche, einige webApi-Methoden aufzurufen Die Meldung "Die Autorisierung wurde für diese Anforderung abgelehnt" wird angezeigt.

Dies ist der Code, den ich implementiert habe.

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());
    }

Routing-Konfiguration:

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 }
        );
    }

Regler:

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

Sie sollten das [AllowAnonymous]-Attribut zur LogInPost Ihres Controllers hinzufügen.

Wenn Sie den Filtern die Variable AuthorizeAttribute hinzugefügt haben, haben Ihre Controller davon ausgegangen, dass sie standardmäßig für alle Aktionen, einschließlich der für die Anmeldung verwendeten, eine Autorisierung erforderlich war.

12
Jonathon Chase

Führen Sie die Windows-Authentifizierung durch? erhalten Sie einen "Zugriff verweigert" Fehler?

Zuweilen macht IISEXpress und IIS einen Trick und um das zu überwinden, habe ich die Site in localis (inetmgr) gehostet, die Authentifizierung (falls vorhanden) aktiviert und jetzt ausführen.

P.S. Standardmäßig ist nicht auf allen Computern der Server IIS installiert. Wenn inetmgr nicht funktioniert, müssen Sie ihn über Systemsteuerung -> Windows-Funktionen -> installieren. Wählen Sie alle Funktionen von IIS und ASP .NET

Hoffe das wird helfen.

3
dotNetAuthor

Entschuldigung für eine solche späte Antwort - Ich habe Ihre Frage gefunden, weil ich, nachdem ich von IIS-gehosteten Web-API zu einer selbst gehosteten Web-API gewechselt habe, gerade das gleiche Problem habe.

In meinem Fall wurde das Problem durch die Initialisierung von Thread.CurrentPrincipal verursacht. Einige hintergrund:

  1. Ich verwende einen benutzerdefinierten AuthenticationHandler (erbt von DelegationHandler)
  2. In diesem Handler überschreibe ich die SendAsync-Methode, um eine benutzerdefinierte Benutzerüberprüfung durchzuführen.
  3. Wenn die Validierung erfolgreich ist, konstruiere ich eine Instanz der ClaimsPrincipal-Klasse, die einige Ansprüche über den aktuellen Benutzer enthält.

Zuvor habe ich diese ClaimsPrincipal-Instanz Thread.CurrentPrincipal zugewiesen, bevor die Nachricht an die verbleibenden Message-Handler in der Pipeline weitergeleitet wurde. Die Lösung für mich bestand jedoch darin, stattdessen den Principal-Member in der HttpRequestContext-Instanz zu verwenden, die zu der HttpRequestMessage-Instanz gehört, die an SendAsync übergeben wird. Daher (in 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...

Hoffe, das kann dir irgendwie helfen.

2
1MuddyDog