2017-10-14 4 views
1

Ich baue derzeit meine erste mobile App in Xamarin.Forms. Die App hat einen Facebook-Login und nachdem der Benutzer angemeldet ist, speichere ich das Facebook-Token, weil ich es als Bearer-Token verwenden möchte, um weitere Anfragen gegen eine API zu authentifizieren.Wie authentifiziere ich facebook web api in asp.net core 2

Die API ist ein .NET Core 2.0-Projekt und ich habe Schwierigkeiten, die Authentifizierung funktioniert zu bekommen.

In meiner Xamarin.Forms App wird das Facebook Token als Bearer-Token mit folgendem Code gesetzt;

_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", UserToken); 

Soweit ich weiß, setzt dies ordnungsgemäß das Bearer-Token in den Headern der Anfrage. Ich habe mit einem Kollegen von mir darüber gesprochen und er hat mir gesagt, dass ich einen Blick auf den Identityserver4 werfen sollte, der dies unterstützen sollte. Aber für jetzt habe ich beschlossen, das nicht zu tun, da es für mich in diesem Moment Overhead ist, dies zu implementieren. Also habe ich beschlossen, bei der Idee zu bleiben, den Facebook-Token als Bearer-Token zu verwenden und dies zu bestätigen.

Der nächste Schritt für mich ist, einen Weg zu finden, den eingehenden Bearer Token mit Facebook zu authentifizieren, um zu überprüfen, ob es (noch) gültig ist. Also habe ich den Start für meine API-Projekte wie folgt konfiguriert;

Aber wenn ich Postbote verwende, um eine Anfrage zu machen und zu testen, ob alles funktioniert, erhalte ich den folgenden Fehler;

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. 

Was mache ich hier falsch?

EDIT: In der Zwischenzeit wenn beschäftigt gewesen versucht, eine Lösung dafür zu finden. Nachdem ich viel auf Google gelesen habe, scheint es, als ob ein Autorisierungshandler im Moment der richtige Weg ist. Von da an kann ich bei facebook nachfragen, ob das Token gültig ist. Ich habe meiner ConfigureServices-Methode den folgenden Code hinzugefügt:

public void ConfigureServices(IServiceCollection services) 
    { 
     //Other code 

     services.AddAuthorization(options => 
     { 
      options.AddPolicy("FacebookAuthentication", policy => policy.Requirements.Add(new FacebookRequirement())); 
     }); 

     services.AddMvc(); 
    } 

Und ich habe eine FacebookRequirement erstellt, die mir helfen wird, die Politik zu behandeln;

public class FacebookRequirement : AuthorizationHandler<FacebookRequirement>, IAuthorizationRequirement 
    { 
     private readonly IHttpContextAccessor contextAccessor; 
     public FacebookRequirement(IHttpContextAccessor contextAccessor) 
     { 
      this.contextAccessor = contextAccessor; 
     } 

     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FacebookRequirement requirement) 
     { 
      //var socialConfig = new SocialConfig{Facebook = new SocialApp{AppId = "MyAppId", AppSecret = "MyAppSecret" } }; 
      //var socialservice = new SocialAuthService(socialConfig); 

      //var result = await socialservice.VerifyFacebookTokenAsync() 
      var httpContext = contextAccessor.HttpContext; 

      if (httpContext != null && httpContext.Request.Headers.ContainsKey("Authorization")) 
      { 
       var token = httpContext.Request.Headers.Where(x => x.Key == "Authorization").ToList(); 
      } 

      context.Succeed(requirement); 

      return Task.FromResult(0); 
     } 
    } 

Das Problem, das ich in jetzt renne ist, dass ich weiß nicht, wo die IHttpContextAccessor zu bekommen. Wird das irgendwie injiziert? Bin ich auf dem richtigen Weg, um dieses Problem zu lösen?

Antwort

0

ich meinen eigenen AuthorizationHandler beenden einen Raum aufaddieren Erstellen eingehende Anfragen gegen Facebook-Token Träger zu validieren. In Zukunft werde ich wahrscheinlich den Identityserver verwenden, um mehrere Login-Typen zu handhaben. Aber jetzt ist Facebook ausreichend.

Unten finden Sie die Lösung für zukünftige Referenzen.

zunächst eine FacebookRequirement Klasse von AuthorizationHandler vererben schaffen;

public class FacebookRequirement : AuthorizationHandler<FacebookRequirement>, IAuthorizationRequirement 
    { 
     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FacebookRequirement requirement) 
     { 
      var socialConfig = new SocialConfig { Facebook = new SocialApp { AppId = "<FacebookAppId>", AppSecret = "<FacebookAppSecret>" } }; 
      var socialservice = new SocialAuthService(socialConfig); 

      var authorizationFilterContext = context.Resource as AuthorizationFilterContext; 
      if (authorizationFilterContext == null) 
      { 
       context.Fail(); 
       return Task.FromResult(0); 
      } 

      var httpContext = authorizationFilterContext.HttpContext; 
      if (httpContext != null && httpContext.Request.Headers.ContainsKey("Authorization")) 
      { 
       var authorizationHeaders = httpContext.Request.Headers.Where(x => x.Key == "Authorization").ToList(); 
       var token = authorizationHeaders.FirstOrDefault(header => header.Key == "Authorization").Value.ToString().Split(' ')[1]; 

       var user = socialservice.VerifyTokenAsync(new ExternalToken { Provider = "Facebook", Token = token }).Result; 
       if (!user.IsVerified) 
       { 
        context.Fail(); 
        return Task.FromResult(0); 
       } 

       context.Succeed(requirement); 
       return Task.FromResult(0); 
      } 

      context.Fail(); 
      return Task.FromResult(0); 
     } 
    } 

Fügen Sie die folgenden Klassen hinzu, die die Konfiguration enthalten und den Benutzer darstellen;

public class SocialConfig 
    { 
     public SocialApp Facebook { get; set; } 
    } 

    public class SocialApp 
    { 
     public string AppId { get; set; } 
     public string AppSecret { get; set; } 
    } 

    public class User 
    { 
     public Guid Id { get; set; } 
     public string SocialUserId { get; set; } 
     public string Email { get; set; } 
     public bool IsVerified { get; set; } 
     public string Name { get; set; } 

     public User() 
     { 
      IsVerified = false; 
     } 
    } 

    public class ExternalToken 
    { 
     public string Provider { get; set; } 
     public string Token { get; set; } 
    } 

Und last but not least, die SocialAuthService Klasse, die die Anfragen mit Facebook behandelt;

Dies validiert das Facebook-Token, das von der Anfrage als Bearer-Token kommt, mit Facebook, um zu überprüfen, ob es noch gültig ist.

+0

mich korrigieren, wenn ich falsch bin, aber dies bedeutet, dass zu Ihren Dienst auf jede Anfrage Sie eine Anfrage an Facebook machen. Das klingt nicht sehr effektiv. – Stilgar

0

Versuchen _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer ", UserToken);

Nach Bearer

+0

Ich glaube nicht, das Problem dadurch lösen. Denn selbst wenn ich Trog Postbote teste ich bin immer der Fehler – Rob

Verwandte Themen