Ich entwickle eine REST-API in ASP.Net Web API. Auf meine API kann nur über nicht browserbasierte Clients zugegriffen werden. Ich muss Sicherheit für meine API implementieren, also entschied ich mich für die Token-basierte Authentifizierung. Ich habe ein faires Verständnis der tokenbasierten Authentifizierung und habe ein paar Tutorials gelesen, aber alle haben eine Benutzeroberfläche für die Anmeldung. Ich benötige keine Benutzeroberfläche für die Anmeldung, da die Anmeldedaten vom Client über HTTP POST übermittelt werden, der von unserer Datenbank autorisiert wird. Wie kann ich Token-basierte Authentifizierung in meiner API implementieren? Bitte beachten Sie, dass auf meine API in hoher Frequenz zugegriffen wird, so dass ich auch auf die Leistung achten muss. Bitte lassen Sie mich wissen, wenn ich es besser erklären kann.Token-basierte Authentifizierung in Web-API ohne Benutzeroberfläche
Antwort
Ich denke, es gibt einige Verwirrung über den Unterschied zwischen MVC und Web API. Kurz gesagt, für MVC können Sie ein Login-Formular verwenden und eine Sitzung mit Cookies erstellen. Für Web Api gibt es keine Sitzung. Deshalb möchten Sie das Token verwenden.
Sie benötigen kein Login-Formular. Der Token-Endpunkt ist alles, was Sie brauchen. Wie bei Win beschrieben, senden Sie die Anmeldeinformationen an den Token-Endpunkt, an dem sie verarbeitet wird.
Hier einige C# -Code Client-Seite ein Token zu erhalten:
//using System;
//using System.Collections.Generic;
//using System.Net;
//using System.Net.Http;
//string token = GetToken("https://localhost:<port>/", userName, password);
static string GetToken(string url, string userName, string password) {
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", userName),
new KeyValuePair<string, string> ("Password", password)
};
var content = new FormUrlEncodedContent(pairs);
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using (var client = new HttpClient()) {
var response = client.PostAsync(url + "Token", content).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
Um das Token fügen Sie es dem Header der Anforderung zu verwenden:
//using System;
//using System.Collections.Generic;
//using System.Net;
//using System.Net.Http;
//var result = CallApi("https://localhost:<port>/something", token);
static string CallApi(string url, string token) {
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using (var client = new HttpClient()) {
if (!string.IsNullOrWhiteSpace(token)) {
var t = JsonConvert.DeserializeObject<Token>(token);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + t.access_token);
}
var response = client.GetAsync(url).Result;
return response.Content.ReadAsStringAsync().Result;
}
}
Wo Token ist:
//using Newtonsoft.Json;
class Token
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string userName { get; set; }
[JsonProperty(".issued")]
public string issued { get; set; }
[JsonProperty(".expires")]
public string expires { get; set; }
}
Jetzt für die Serverseite:
In Startup.Auth.cs
var oAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider("self"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// https
AllowInsecureHttp = false
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(oAuthOptions);
Und in ApplicationOAuthProvider.cs dem Code, der tatsächlich gewährt oder Zugriff verweigert:
//using Microsoft.AspNet.Identity.Owin;
//using Microsoft.Owin.Security;
//using Microsoft.Owin.Security.OAuth;
//using System;
//using System.Collections.Generic;
//using System.Security.Claims;
//using System.Threading.Tasks;
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
public ApplicationOAuthProvider(string publicClientId)
{
if (publicClientId == null)
throw new ArgumentNullException("publicClientId");
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager);
var propertyDictionary = new Dictionary<string, string> { { "userName", user.UserName } };
var properties = new AuthenticationProperties(propertyDictionary);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
// Token is validated.
context.Validated(ticket);
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// Resource owner password credentials does not provide a client ID.
if (context.ClientId == null)
context.Validated();
return Task.FromResult<object>(null);
}
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
var expectedRootUri = new Uri(context.Request.Uri, "/");
if (expectedRootUri.AbsoluteUri == context.RedirectUri)
context.Validated();
}
return Task.FromResult<object>(null);
}
}
Wie man dort sehen kann kein Controller in das Abrufen der Token beteiligt ist. In der Tat können Sie alle MVC-Referenzen entfernen, wenn Sie nur eine Web-API möchten. Ich habe den serverseitigen Code vereinfacht, um ihn lesbarer zu machen. Sie können Code hinzufügen, um die Sicherheit zu aktualisieren.
Stellen Sie sicher, dass Sie nur SSL verwenden. Implementieren Sie das RequireHttpsAttribute, um dies zu erzwingen.
Sie können die Attribute Authorize/AllowAnonymous verwenden, um Ihre Web API zu sichern. Zusätzlich können Sie Filter (wie RequireHttpsAttribute) hinzufügen, um Ihre Web-API sicherer zu machen. Ich hoffe das hilft.
sagte "für MVC können Sie ein Login-Formular verwenden und erstellen Sie eine Sitzung mit Cookies. Für Web-API gibt es keine Sitzung" aber Formularauthentifizierung kann in Web-API implementiert werden. So kann der Client die Zugangsdaten an die Web-API senden, und die Web-API gibt den Authentifizierungs-Cookie an den Client aus. für alle nachfolgenden Call-Client muss auth Cookie an Web-API übergeben ...... ich denke, das ist möglich. –
Ihren Code wie folgt auswählen. 'new KeyValuePair
Die ASP.Net-Web-API verfügt bereits über den Authorization Server-Build. Sie können es innerhalb Startup.cs sehen, wenn Sie eine neue ASP.Net-Webanwendung mit Web-API-Vorlage erstellen.
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
Alles, was Sie tun müssen, ist zu URL codiert Benutzername und Passwort innerhalb Query-String zu schreiben.
/Token/userName=johndoe%40example.com&password=1234&grant_type=password
Wenn Sie mehr Details wissen möchten, können Sie User Registration and Login - Angular Front to Back with Web API by Deborah Kurata beobachten.
Also werde ich eine POST-Anfrage an/TOKEN mit Benutzername und Passwort in der HTTP Header/Body erstellen? Ich werde einen Benutzernamen und ein Hash-Passwort für alle Benutzer in meiner App-Datenbank haben. Wie soll ich das umsetzen? –
Sie benötigen ASP.Net Identity * (ich glaube, Sie haben bereits eine) *. Wenn nicht, erstellen Sie ein ASP.Net-Web-API-Projekt und sehen Sie sich den Quellcode an. – Win
Was ist Grant_type = Passwort? Bitte teile Wissen. Danke, –
- 1. Verwenden Sie WebAPI 2 ohne OWIN Authentifizierung Middleware
- 2. Laravel 5.2 tokenbasierte Authentifizierung vs JWT
- 3. .NET WebApi-Authentifizierung
- 4. Client-Authentifizierung für WebAPI 2
- 5. Aktivität ohne Benutzeroberfläche
- 6. BlackBerry App ohne Benutzeroberfläche
- 7. ASP.NET MVC 5 und WebApi 2 Authentifizierung
- 8. AngularJs -.net MVC WebApi Authentifizierung Beispiel
- 9. Cross-Domain-Cookie-Authentifizierung Problem WebApi ASP.NET
- 10. Authentifizierung mit oAuth und ASP.NET MVC + WebApi
- 11. MVC WebAPI-Authentifizierung von Windows Forms
- 12. SignalR-Authentifizierung mit webAPI Bearer Token
- 13. AngularJs ASP.NET WebApi Authentifizierung mit Thinktecture
- 14. Android: Nimm Foto ohne Benutzeroberfläche
- 15. Authentifizierung in WebAPI mit OAuth-Bearer-Aufrufstil in WS-Federation?
- 16. WebAPI ODATA ohne Entity Framework
- 17. WebAPI POST funktioniert ohne [FromBody]?
- 18. Was ist der richtige Weg, tokenbasierte Authentifizierung mit APIRequestFactory zu testen?
- 19. SuppressDefaultHostAuthentication in WebApi.Owin unterdrückt auch Authentifizierung außerhalb von Webapi
- 20. RabbitMQ Authentifizierung ohne Passwort
- 21. MySQL-Leistung ohne Authentifizierung
- 22. SmtpClient Senden ohne Authentifizierung
- 23. Wie ohne Authentifizierung
- 24. Twitter Authentifizierung ohne Pin
- 25. ADAL-Authentifizierung ohne Dialogfeldaufforderung
- 26. HTTP-Authentifizierung ohne Popup?
- 27. Authentifizierung von Gitweb mit Gitosis ohne LDAP-Authentifizierung?
- 28. Silex/Symfony2 Remember Me Authentifizierung Benutzeroberfläche RedBean Wrapper
- 29. AngularJS clientside Routing und Token-Authentifizierung mit Webapi
- 30. WebAPI JSON-Array ohne Stammknoten zurückgeben
jemand, irgendwo müsste den Benutzernamen und das Passwort eingeben, um die anfängliche Validierung durchzuführen; schlagen Sie vor, dass jeder, der eine Kopie Ihrer App erhält, denselben Benutzernamen und dasselbe Passwort verwendet? und wenn das der Fall ist, beabsichtigen Sie, den Benutzernamen und das Kennwort in Ihrem Code fest zu codieren? – Claies
Ich kann mehrere registrierte Benutzer haben, daher werden die ursprünglichen Anmeldedaten von ihnen über HTTP POST weitergeleitet. Weiter ist was? –
das macht keinen Sinn. Wie können Sie Anmeldeinformationen an Ihren Client weiterleiten? Wie soll der Server wissen, welcher Client welcher ist? – Claies