it-swarm.com.de

Standardauthentifizierung in ASP.NET MVC 5

Welche Schritte sind erforderlich, um die Basisauthentifizierung in ASP.NET MVC 5 zu implementieren?

Ich habe gelesen, dass OWIN keine cookieless-Authentifizierung unterstützt. Ist eine Standardauthentifizierung generell möglich?

Benötige ich hier ein benutzerdefiniertes Attribut? Ich bin nicht sicher, wie diese Attribute funktionieren.

33
Sonic

Sie können diesen einfachen, aber effektiven Mechanismus mithilfe eines benutzerdefinierten ActionFilter-Attributs verwenden:

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected string Username { get; set; }
    protected string Password { get; set; }

    public BasicAuthenticationAttribute(string username, string password)
    {
        this.Username = username;
        this.Password = password;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var req = filterContext.HttpContext.Request;
        var auth = req.Headers["Authorization"];
        if (!String.IsNullOrEmpty(auth))
        {
            var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
            var user = new { Name = cred[0], Pass = cred[1] };
            if (user.Name == Username && user.Pass == Password) return;
        }
        filterContext.HttpContext.Response.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
        /// thanks to eismanpat for this line: http://www.ryadel.com/en/http-basic-authentication-asp-net-mvc-using-custom-actionfilter/#comment-2507605761
        filterContext.Result = new HttpUnauthorizedResult();
    }
}

Es kann verwendet werden, um unter "Standardauthentifizierung" einen gesamten Controller zu definieren:

[BasicAuthenticationAttribute("your-username", "your-password", 
    BasicRealm = "your-realm")]
public class HomeController : BaseController
{
   ...
}

oder ein bestimmtes ActionResult:

public class HomeController : BaseController
{
    [BasicAuthenticationAttribute("your-username", "your-password", 
        BasicRealm = "your-realm")]
    public ActionResult Index() 
    {
        ...
    }
}

Falls Sie zusätzliche Informationen benötigen, lesen Sie diesen Blogpost , den ich zum Thema geschrieben habe.

68
Darkseal

Sie können dies mit einem benutzerdefinierten Attribut tun. Es gibt eine Implementierung eines benutzerdefinierten Attributs, das die Basisauthentifizierung im Open Source-Projekt SimpleSecurity unterstützt, das Sie hier herunterladen herunterladen können. Es gibt eine Referenzanwendung, um die Verwendung zu demonstrieren. Es wurde ursprünglich für die Zusammenarbeit mit SimpleMembership in MVC 4 entwickelt und wurde kürzlich portiert zur Verwendung von ASP.NET Identity in MVC 5

13
Kevin Junghans

Ich wollte die Antwort, die Darkseal geteilt hat, ändern, da dieser Code einen großen Sicherheitsfehler aufweist. Wie geschrieben, beendet der Aktionsfilter die Anforderung nicht wirklich, wenn res.End () aufgerufen wird. Der Benutzer wird zur Eingabe der Anmeldeinformationen aufgefordert, und eine Antwort 401 wird zurückgegeben, wenn die Anmeldeinformationen nicht übereinstimmen. Die Controller-Aktion wird jedoch weiterhin auf der Serverseite ausgeführt. Sie müssen die filterContext.Result -Eigenschaft auf etwas festlegen, damit die Anforderung ordnungsgemäß beendet wird und nicht mit der Aktionsmethode fortgefahren wird. 

Dies war besonders schlecht für meine Situation, da ich einen Web-Service-Endpunkt schützen wollte, der einen Daten-Feed von einem Drittanbieter erhält. Wie gesagt, dieser Aktionsfilter schützte nichts, da die Daten immer noch durch meine Aktionsmethode gepusht wurden.

Meine "schnelle Lösung" ist unten:

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected string Username { get; set; }
    protected string Password { get; set; }

    public BasicAuthenticationAttribute(string username, string password)
    {
        this.Username = username;
        this.Password = password;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var req = filterContext.HttpContext.Request;
        var auth = req.Headers["Authorization"];
        if (!String.IsNullOrEmpty(auth))
        {
            var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
            var user = new { Name = cred[0], Pass = cred[1] };
            if (user.Name == Username && user.Pass == Password) return;
        }
        var res = filterContext.HttpContext.Response;
        res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
        filterContext.Result = new HttpUnauthorizedResult();
    }
}
5
PatrickGaule

Tolle Antwort von @Darkseal. Hier ist derselbe Code für die Verwendung mit der ASP.NET-Web-API (in der Nähe von MVC) enthalten. Gleiche Idee, etwas unterschiedliche Namespaces und Kontextklassen. Fügen Sie es Ihren Klassen und Methoden auf dieselbe Weise hinzu.

using System.Web.Http.Controllers;
using System.Web.Http.Filters;

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public string BasicRealm { get; set; }
    protected string Username { get; set; }
    protected string Password { get; set; }

    public BasicAuthenticationAttribute(string username, string password)
    {
        Username = username;
        Password = password;
    }

    public override void OnActionExecuting(HttpActionContext filterContext)
    {
        var req = filterContext.Request;
        var auth = req.Headers.Authorization;
        if (auth?.Scheme == "Basic")
        {
            var cred = Encoding.ASCII.GetString(Convert.FromBase64String(auth.Parameter)).Split(':');
            var user = new { Name = cred[0], Pass = cred[1] };
            if (user.Name == Username && user.Pass == Password) return;
        }
        filterContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        filterContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", BasicRealm ?? "YourRealmName"));
    }
}
2
Neil Laslett

Für die HTTP-Basisauthentifizierung ist kein Cookie erforderlich. Es basiert auf einem HEADER in der HTTP-Anfrage. Der Header hat den Namen Authorization und sein Wert sollte aus Benutzername und Kennwort bestehen, die in einer Zeichenfolge "Benutzername: Kennwort" (alle Base64-kodiert) zusammengefasst sind.

Mit freundlichen Grüßen habe ich nie die Basisauthentifizierung mit ASP.NET MVC verwendet, aber ich habe die Web-API verwendet, um ein benutzerdefiniertes Attribut zu erstellen (Sie können von hier für WebAPI oder hier für MVC beginnen).

2
imperugo

sie können dieses Paket unter Nuget (AuthPackage) ausprobieren. Mit diesem können Sie Ihre asp.net-mvc-Authentifizierung problemlos hinzufügen.

  1. paket mit der Package Manager Console installieren:

    Install-Package AuthPackage

  2. fügen Sie Ihrer Web.config in (appSettings) eine Verbindungszeichenfolge hinzu:

     <add key="connectionString" value="connectionStringHere" />
    
  3. sie sind bereit, Benutzer zu registrieren, sich anzumelden und sich abzumelden

beispiel:

 public async Task<ActionResult> SignIn()
    {
        var context = System.Web.HttpContext.Current;
        AuthUser authUser = new AuthUser(context);
        await authUser.SignIn("[email protected]", "123456");
        return RedirectToAction("Index", "Home");
    }

Sie können die Dokumentation hier lesen.

1
Waleed Chayeb

Eine Anwendung von uns "versehentlich" verwendete die Basisauthentifizierung aufgrund des folgenden Codes in Web.config:

<system.webServer>
    <modules>
        <remove name="FormsAuthentication" />
    </modules>
    ... other stuff
</system.webServer>

Die Anwendung ist ansonsten so konfiguriert, dass sie die Formularauthentifizierung verwendet. Das Fenster zur Browserauthentifizierung wurde immer dann geöffnet, wenn die normale Formularauthentifizierung verwendet worden wäre.

0
Charles Burns