none
WEB API 2 Autenticação oauth, como utilizar parametros adicionais ? RRS feed

  • Pergunta

  • Estou desenvolvendo um Web API 2 com fluxo de autenticação "OAuth Client Credentials", onde primeira chamada para obter otoken de autorização, eu preciso de um parâmetro adicional para ser acessado posteriormente nos controllers sem a necessidade de trafegá-lo novamente levando em consideração questões de segurança.

    Qual a melhor maneira de passar esse parâmetro ?

    Encontrei alguns desenvolvedores passando esses parâmetros na URL, e adicionando-o ao OWinContext:

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
    
            string clientId;
            string clientSecret;
            if (context.TryGetBasicCredentials(out clientId, out clientSecret) ||
                context.TryGetFormCredentials(out clientId, out clientSecret))
            {
                try
                {
                    if (context.Parameters.Any(x => x.Key == "Participant"))
                    {
                        // Get Participant(Parâmetro Adicional)
                        string participant = context.Parameters.First(x => x.Key == "participant").Value[0];
    
                        //Validating Client
                        Microsoft.AspNet.Identity.PasswordHasher passwordHaser = new Microsoft.AspNet.Identity.PasswordHasher();
                        Client client = _clientAppService.GetById(Guid.Parse(clientId));
    
                        if (client != null && passwordHaser.VerifyHashedPassword(client.SecretHash, clientSecret) == Microsoft.AspNet.Identity.PasswordVerificationResult.Success)
                        {
                            context.OwinContext.Set<Client>("oauth:client", client);
                            //Armazenar Participant(Parametro Adicional)
                            context.OwinContext.Set<Participant>("urn:participant", new Participant { Document = participant });
                            context.Validated();
                        }
                        else
                        {
                            context.SetError("invalid_client", "Client credentials are invalid.");
                            context.Rejected();
                        }
                    }
                    else
                    {
                        context.SetError("invalid_request", "Participant are invalid.");
                        context.Rejected();
                    }
                }
                catch (Exception)
                {
                    context.SetError("server_error");
                    context.Rejected();
                }
            }
            else
            {
                context.SetError("invalid_client", "Client credentials could not be retrieved through the Authorization header.");
                context.Rejected();
            }
    
            return Task.FromResult(0);
        }

    E eu estou acessar esse parâmetros através de um ModelBinder, infelizmente OWincontext sempre retorna null:

    public class ParticipantModelBinder : IModelBinder
        {
            public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
            {
                //Retorna null
                Participant participant = HttpContext.Current.GetOwinContext().Get<Participant>("urn:participant");
                bindingContext.Model = participant;
    
                return true;
            }
        }

    Controlle:

    [Authorize]
        public class ParticipantController : ApiController
        {
            public decimal GetBalance([ModelBinder(BinderType=typeof(ParticipantModelBinder))] Participant participant)
            {
                return 0;
            }
        }

    E outra solução que eu encontrei é adicionar uma nova Claim no método GrantClientCredentials, porém não consigo obter esse valor no controller:

    public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
        {
            //Client validated, generate token
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            Client client = context.OwinContext.Get<Client>("oauth:client");
            if (client.AllowedGrant == OAuthGrant.Client)
            {
                ClaimsIdentity identity = new ClaimsIdentity(new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType));
                identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
                // Add an custum Claim with the additional parameter
                identity.AddClaim(new Claim("Participant", context.OwinContext.Get<Participant>("urn:participant").Document));
                context.Validated(identity);
            }
            else
            {
                context.SetError(
                    "unauthorized_client",
                    "The authenticated client is not authorized to use this authorization grant type");
            }
    
            return Task.FromResult(0);
        }

    Obrigado !!!

    quarta-feira, 18 de março de 2015 20:56