Wie Verwenden Sie Active Directory-Authentifizierung mit ASP.NET Web-API?
Haben wir eine Web-API-Anwendung, die bietet eine Reihe von web-Methoden, die Kunden können anrufen und konsumieren. Es wird gehostet im IIS-und SSL-setup.
Werden die Anmeldeinformationen des Benutzers in Active Directory gespeichert, aber die Kunden sind nicht nur innerhalb unserer Domäne, Sie können überall in der Welt, also wir, mein Verständnis ist, können wir nicht verwenden die Integrierte Windows-Authentifizierung.
Was ist der beste Weg, um die Benutzer zu authentifizieren, die in unserem Szenario wie oben erklärt?
Sollte ich die Fragen der Benutzer zu übergeben Benutzername/Passwort in den header mit jeder Anfrage die Sie machen? Dann habe ich überprüfen die Anmeldeinformationen der Anwender gegen unser Active Directory programmgesteuert (wir haben bereits eine Komponente, die bedeutet, dass z.B. durch die Erstellung einer benutzerdefinierten ActionFilter läuft vor jeder Aktion ausgeführt?
Ein anderer Ansatz wäre vielleicht zu schaffen, ein HttpModule, das ausgeführt wird, bevor jede Anforderung und übernimmt die Authentifizierung und wenn es ungültig ist, bricht die Anfrage.
Mein Benutzerdefiniertes Attribut würde dann so Aussehen:
public class ActiveDirectoryAuthAttribute : ActionFilterAttribute
{
//todo: load from config which can change depending on deployment environment
private static readonly bool ShouldRequireHttps = false;
public override void OnActionExecuting(HttpActionContext actionContext)
{
IPrincipal principal = this.Authentiate(actionContext);
if (principal == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
else
{
this.SetPrincipal(principal);
}
}
private IPrincipal Authentiate(HttpActionContext actionContext)
{
if (IsUriSchemaValid(actionContext.Request.RequestUri))
{
//is the client certificate known and still valid?
//is IP valid?
//find user credentials and validate against AD
//create the Principle object and return it
}
return null;
}
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private static bool IsUriSchemaValid(Uri uri)
{
bool result = true;
if (ShouldRequireHttps)
{
if (!string.Equals(uri.Scheme, "https", StringComparison.InvariantCultureIgnoreCase))
{
result = false;
}
}
return result;
}
}
Dann in meine controller-action bekomme ich Zugriff auf die Grundsatz-Objekt:
IPrincipal principle = this.User;
Was ist der beste Weg, sich zu authentifizieren/autorisieren der Benutzer in unserem Szenario wie oben erklärt?
Oben, wie Sie ein Objekt erstellen aus IPrinciple? Ist es bereits .NET-Klasse oder müsste ich, um meine custom class?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich gemacht, ein gutes Stück, die mit AD in letzter Zeit und ich kann mir nicht vorstellen eine andere Art des Umgangs mit diesen, um ehrlich zu sein.
Macht es mehr Sinn, einen OAuth-Typ-Ansatz. Bieten einen token-Typ route finden, den Benutzernamen und das Passwort anfangs-und zurück eine selbst-erstellte und verschlüsselte token zurück zu dem angerufenen. Einmal ersten ersten Aufruf senden Sie das token an die aufgerufene und dann Sie können verwenden, dass der token die in der Genehmigung header bei jedem nachfolgenden Aufruf der API.
Token gültig für einen Anruf oder ein sehr kurzer Zeit. Jedes mal, wenn Sie halten das token verwendet werden, Problem ein anderes.
Könnte man auch mit einer custom OAuth-Implementierung für diese und anstatt verwenden Sie eine Datenbank für die Authentifizierung verwenden Sie Ihre AD-Identität speichern und verwenden von OAuth Bearer Token. Da bist du mit SSL, das ist tatsächlich eine gute Passform für Ihr Szenario.