2015-02-05 17 views
10

Ho implementato l'autenticazione OAuth nel mio progetto Api Web basata on these blog postsUtilizzando sia OAuth e Auth di base in Asp.Net Web API con Owin

Funziona bene, compresa la logica del token di aggiornamento.

Desidero aggiungere un'opzione per l'autenticazione di base anche per un paio di chiamate per i lavori pianificati.

Ho provato ad aggiungere una soluzione di autenticazione di base come middleware ma sto ancora ricevendo 401 chiedendo il token Bearer.

Posso farlo funzionare rimuovendo l'attributo [Autorizza] da quelle chiamate API e controllando manualmente nel codice se l'utente è autenticato ma sembra il modo sbagliato per risolverlo.

C'è un modo per supportare l'autenticazione di base e OAuth utilizzando OWin?

risposta

7

Come su attribuisci vostre azioni o controller con si desidera implementare l'autenticazione di base con l'attributo [OverrideAuthentication] Quindi si crea attributo di filtro di autenticazione personalizzato che eredita da Attribute, IAuthenticationFilter come il codice qui sotto

public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter 
{ 
    public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) 
    { 
     var req = context.Request; 
     // Get credential from the Authorization header 
     //(if present) and authenticate 
     if (req.Headers.Authorization != null && "basic".Equals(req.Headers.Authorization.Scheme, StringComparison.OrdinalIgnoreCase)) 
     { 
      var rawCreds = req.Headers.Authorization.Parameter; 

      var credArray = GetCredentials(rawCreds); 

      var clientId = credArray[0]; 
      var secret = credArray[1]; 

      if (ValidCredentials(clientId, secret)) 
      { 
       var claims = new List<Claim>() 
         { 
         new Claim(ClaimTypes.Name, clientId) 
         }; 

       var identity = new ClaimsIdentity(claims, "Basic"); 
       var principal = new ClaimsPrincipal(new[] { identity }); 
       // The request message contains valid credential 
       context.Principal = principal; 
      } 
      else 
      { 
       context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request); 
      } 

     } 
     else 
     { 
      context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request); 
     } 

     return Task.FromResult(0); 
    } 

    private string[] GetCredentials(string rawCred) 
    { 

     var encoding = Encoding.GetEncoding("UTF-8"); 

     var cred = encoding.GetString(Convert.FromBase64String(rawCred)); 

     var credArray = cred.Split(':'); 

     if (credArray.Length == 2) 
     { 
      return credArray; 
     } 
     else 
     { 
      return credArray = ":".Split(':'); 
     } 

    } 

    private bool ValidCredentials(string clientId, string secret) 
    { 

     //compare the values from web.config 

     if (clientId == secret) 
     { 
      return true; 
     } 
     return false; 
    } 

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context,CancellationToken cancellationToken) 
    { 
     context.Result = new ResultWithChallenge(context.Result); 
     return Task.FromResult(0); 
    } 

    public class ResultWithChallenge : IHttpActionResult 
    { 
     private readonly IHttpActionResult next; 
     public ResultWithChallenge(IHttpActionResult next) 
     { 
      this.next = next; 
     } 
     public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
     { 
      var response = await next.ExecuteAsync(cancellationToken); 
      if (response.StatusCode == HttpStatusCode.Unauthorized) 
      { 
       response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic")); 
      } 
      return response; 
     } 
    } 

    public bool AllowMultiple 
    { 
     get { return false; } 
    } 
} 

Ora lo si utilizza per attribuisci controllori o azioni come il codice qui sotto:

[OverrideAuthentication] 
    [BasicAuthentication] 
    [Route("")] 
    public async Task<IHttpActionResult> Get() 
{ 
} 

Notate come stiamo creando reclami identità e impostare lo schema di autenticazione di base, è possibile pu tutte le richieste che vuoi qui.

+0

Ho usato filtri per l'autenticazione personalizzata nei progetti precedenti, credo che per alcune chiamate in un'API che utilizza principalmente altri schemi di autenticazione questo ha più senso di un middleware Owin che viene eseguito su ogni chiamata alla ricerca di un'intestazione di autenticazione di base – EShy

Problemi correlati