Hallo Leute,
ich habe die Aufgabe bekommen einen Web-API-Service zu realisieren (nennt man das so?). Diverse Tutorials habe ich durch und im Browser zeigte mir mein Webservice auch Daten an. Ich möchte anstatt XML JSON verwenden (in- und output).
Bei zwei Problemen, zu denen ich bisher keine Lösung bei google gefunden habe, bräuchte ich Eure Hilfe:
1.) Ich starte das Projekt in Visual Studio, daraufhin öffnet sich der Browser und ich kann mit der entsprechenden URL auch Abfragen machen. Wie bringe ich Visual Studio dazu bei Haltepunkten zu halten, so dass ich die Funktionen debuggen kann? Bisher werden diese überhaupt nicht angesprungen.
2.) Ich habe bei stackoverflow ein Beispiel für eine Authentifizierung gefunden, bekomme es aber nicht zum Laufen und verstehe nicht warum:
[Authorize]
public class KundenController : ApiController
{
private List<Kunde> _Kunden;
public KundenController()
{
this._Kunden = new List<Kunde>();
this._Kunden.Add(new Kunde { KundenNr = "1", Name1 = "Meier", Name2 = "Metallbau", EMail = "info@meier.de", Ort = "Musterdorf", PLZ = "12345", Strasse = "Musterstrasse 100" });
this._Kunden.Add(new Kunde { KundenNr = "2", Name1 = "Peter Klaus", Name2 = "", EMail = "info@klaus.de", Ort = "Musterdorf", PLZ = "12345", Strasse = "Musterstrasse 60" });
}
// http://localhost:7080/api/kunden
// GET: api/Kunden
public IEnumerable<Kunde> Get()
{
return this._Kunden;
}
public class AuthController : ApiController
{
public bool Post(AuthModel model)
{
return true;
if (model.Username == "john" && model.Passwort == "secret")
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return true;
}
return false;
}
}
public class AuthModel
{
public string Username { get; set; }
public string Passwort { get; set; }
}
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
}
Wenn ich jetzt mit einem Testprogramm die Kunden abfragen machen möchte, dann kommt die Meldung "Response status code does not indicate success: 401 (Unauthorized)."
try
{
using (var httpClient = new HttpClient())
{
string url = "http://localhost:7080/api/auth";
var response = httpClient.PostAsJsonAsync(url,
new { Username = "john" Passwort = "secret" },
CancellationToken.None
).Result;
response.EnsureSuccessStatusCode();
bool success = response.Content.ReadAsAsync<bool>().Result;
if (success)
{
url = "http://localhost:7080/api/kunden";
var secret = httpClient.GetStringAsync(url);
textBox1.Text = secret.Result;
}
else
{
textBox1.Text = "Sorry you provided wrong credentials";
}
}
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
Wenn ich [Authorize] aus der Klasse KundenController entferne kommt die Meldung "> Fehlermeldung:
Response status code does not indicate success: 401 (Unauthorized)." komischerweise immer noch 🤔
Habt Ihr eine Idee was ich falsch mache?
Danke & Gruß
fungi
Ist eigentlich alles in der Doku beschrieben, wie man es korrekt macht:
https://www.asp.net/web-api/overview/security
FormsAuthentication mit einer API ist nicht wirklich so praktisch.
Normalerweise arbeitet man hier einfach mit Token, die man bei einer Anfrage mitgibt. Sich vorher zu authentifizieren und immer einen Cookie mit zu schleppen ist keine gängige Art bei APIs.
Und wenn die DPAPI im Hintergrund genutzt wird (zB bei den 3.5er Microsoft.* Namespaces) dann ist das auch nicht Load-balancing fähig, da die DPIAPI nur pro Maschine gilt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ne, i.d.R. hast Du eh HTTPS Verbindungen und packst den Token in den Header (zB Basic Auth). So bleibt der Token verborgen (außer SSL Interception).
Im Prinzip funktionieren alle großen APIs, Facebook, Google, Twitter...
Cookies sind bei APIs normalerweise nicht am Werk.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo fungi35,
ich würde erstmal deine normale API zum Laufen bekommen wollen und dann mit Auth starten. Auth beschränkt ja deinen Zugriff auf die API, wenn du eben nicht autorisiert bist. Daher: Mach dir ein WebAPI Projekt, gibt die richtigen Statuscodes zurück und schaue, dass du beim Aufruf in deine Breakpoints im Visual Studio läufst. Kannst du einfach setzen und sollten dann erreicht werden, wenn du im Browser und/oder Postman beispielsweise die richtige Adresse angibst.
Danach dann Auth...
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Ne, i.d.R. hast Du eh HTTPS Verbindungen und packst den Token in den Header (zB Basic Auth). So bleibt der Token verborgen (außer SSL Interception).
Im Prinzip funktionieren alle großen APIs, Facebook, Google, Twitter...
Ich hätte ein Cookie geschickt aufgrund von:
Tokens can also be transmitted via browser cookies. Which transport method you choose (headers or cookies) depends on your application and use case. For mobile applications, headers are the way to go.
For web applications, we recommend using HttpOnly cookies instead of HTML5 storage/headers, for better security against XSS attacks.