Saltar al contenido

¿Cómo obtengo un token de autenticación OAuth 2.0 en C #?

Por fin después de mucho batallar ya encontramos la contestación de esta impedimento que muchos de nuestros usuarios de nuestro sitio web han presentado. Si tienes algo que aportar no dejes de dejar tu comentario.

Solución:

En Cartero, haga clic en Generar codigo y luego en Generar fragmentos de código cuadro de diálogo puede seleccionar un lenguaje de codificación diferente, incluido C # (RestSharp).

Además, solo debería necesitar la URL del token de acceso. Los parámetros del formulario son entonces:

grant_type=client_credentials
client_id=abc    
client_secret=123

Fragmento de código:

/* using RestSharp; // https://www.nuget.org/packages/RestSharp/ */

var client = new RestClient("https://service.endpoint.com/api/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=abc&client_secret=123", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Desde el cuerpo de respuesta, puede obtener su token de acceso. Por ejemplo, para un Portador tipo de token, puede agregar el siguiente encabezado a las solicitudes autenticadas posteriores:

request.AddHeader("authorization", "Bearer ");

¡La respuesta de Rest Client es perfecta! (Lo voté a favor)

Pero, por si acaso quieres ir “crudo”

……….

Conseguí que esto funcionara con HttpClient.

/*
.nugetpackagesnewtonsoft.json12.0.1
.nugetpackagessystem.net.http4.3.4
*/

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;


    private static async Task GetElibilityToken(HttpClient client)
    
        string baseAddress = @"https://blah.blah.blah.com/oauth2/token";

        string grant_type = "client_credentials";
        string client_id = "myId";
        string client_secret = "shhhhhhhhhhhhhhItsSecret";

        var form = new Dictionary
                
                    "grant_type", grant_type,
                    "client_id", client_id,
                    "client_secret", client_secret,
                ;

        HttpResponseMessage tokenResponse = await client.PostAsync(baseAddress, new FormUrlEncodedContent(form));
        var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
        Token tok = JsonConvert.DeserializeObject(jsonContent);
        return tok;
    


internal class Token

    [JsonProperty("access_token")]
    public string AccessToken  get; set; 

    [JsonProperty("token_type")]
    public string TokenType  get; set; 

    [JsonProperty("expires_in")]
    public int ExpiresIn  get; set; 

    [JsonProperty("refresh_token")]
    public string RefreshToken  get; set; 
       

Aquí hay otro ejemplo de trabajo (basado en la respuesta anterior) … con algunos ajustes más. A veces, el servicio de token es delicado:

    private static async Task GetATokenToTestMyRestApiUsingHttpClient(HttpClient client)
    
        /* this code has lots of commented out stuff with different permutations of tweaking the request  */

        /* this is a version of asking for token using HttpClient.  aka, an alternate to using default libraries instead of RestClient */

        OAuthValues oav = GetOAuthValues(); /* object has has simple string properties for TokenUrl, GrantType, ClientId and ClientSecret */

        var form = new Dictionary
                
                     "grant_type", oav.GrantType ,
                     "client_id", oav.ClientId ,
                     "client_secret", oav.ClientSecret 
                ;

        /* now tweak the http client */
        client.DefaultRequestHeaders.Clear();
        client.DefaultRequestHeaders.Add("cache-control", "no-cache");

        /* try 1 */
        ////client.DefaultRequestHeaders.Add("content-type", "application/x-www-form-urlencoded");

        /* try 2 */
        ////client.DefaultRequestHeaders            .Accept            .Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));//ACCEPT header

        /* try 3 */
        ////does not compile */client.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

        ////application/x-www-form-urlencoded

        HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, oav.TokenUrl);
        /////req.RequestUri = new Uri(baseAddress);

        req.Content = new FormUrlEncodedContent(form);

        ////string jsonPayload = ""grant_type":"" + oav.GrantType + "","client_id":"" + oav.ClientId + "","client_secret":"" + oav.ClientSecret + """;
        ////req.Content = new StringContent(jsonPayload,                                                Encoding.UTF8,                                                "application/json");//CONTENT-TYPE header

        req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

        /* now make the request */
        ////HttpResponseMessage tokenResponse = await client.PostAsync(baseAddress, new FormUrlEncodedContent(form));
        HttpResponseMessage tokenResponse = await client.SendAsync(req);
        Console.WriteLine(string.Format("HttpResponseMessage.ReasonPhrase='0'", tokenResponse.ReasonPhrase));

        if (!tokenResponse.IsSuccessStatusCode)
        
            throw new HttpRequestException("Call to get Token with HttpClient failed.");
        

        var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
        Token tok = JsonConvert.DeserializeObject(jsonContent);

        return tok;
    

ADJUNTAR

¡Material extra!

Si alguna vez obtienes un

“El certificado remoto no es válido según el procedimiento de validación”.

excepción … puedes conectar un controlador para ver qué está pasando (y masajear si es necesario)

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Net;

namespace MyNamespace

    public class MyTokenRetrieverWithExtraStuff
    
        public static async Task GetElibilityToken()
        
            using (HttpClientHandler httpClientHandler = new HttpClientHandler())
            
                httpClientHandler.ServerCertificateCustomValidationCallback = CertificateValidationCallBack;
                using (HttpClient client = new HttpClient(httpClientHandler))
                
                    return await GetElibilityToken(client);
                
            
        

        private static async Task GetElibilityToken(HttpClient client)
        
            // throws certificate error if your cert is wired to localhost // 
            //string baseAddress = @"https://127.0.0.1/someapp/oauth2/token";

            //string baseAddress = @"https://localhost/someapp/oauth2/token";

        string baseAddress = @"https://blah.blah.blah.com/oauth2/token";

        string grant_type = "client_credentials";
        string client_id = "myId";
        string client_secret = "shhhhhhhhhhhhhhItsSecret";

        var form = new Dictionary
                
                    "grant_type", grant_type,
                    "client_id", client_id,
                    "client_secret", client_secret,
                ;

            HttpResponseMessage tokenResponse = await client.PostAsync(baseAddress, new FormUrlEncodedContent(form));
            var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
            Token tok = JsonConvert.DeserializeObject(jsonContent);
            return tok;
        

        private static bool CertificateValidationCallBack(
        object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate,
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors sslPolicyErrors)
        
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            
                return true;
            

            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            
                if (chain != null && chain.ChainStatus != null)
                
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    
                        if ((certificate.Subject == certificate.Issuer) &&
                           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        
                            // Self-signed certificates with an untrusted root are valid. 
                            continue;
                        
                        else
                        
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                return false;
                            
                        
                    
                

                // When processing reaches this line, the only errors in the certificate chain are 
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange server installations, so return true.
                return true;
            


            /* overcome localhost and 127.0.0.1 issue */
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
            
                if (certificate.Subject.Contains("localhost"))
                
                    HttpRequestMessage castSender = sender as HttpRequestMessage;
                    if (null != castSender)
                    
                        if (castSender.RequestUri.Host.Contains("127.0.0.1"))
                        
                            return true;
                        
                    
                
            

            return false;

        


        public class Token
        
            [JsonProperty("access_token")]
            public string AccessToken  get; set; 

            [JsonProperty("token_type")]
            public string TokenType  get; set; 

            [JsonProperty("expires_in")]
            public int ExpiresIn  get; set; 

            [JsonProperty("refresh_token")]
            public string RefreshToken  get; set; 
        

    

……………………

Recientemente encontré (enero / 2020) un artículo sobre todo esto. Agregaré un enlace aquí … a veces, tener 2 personas diferentes que lo muestren / expliquen ayuda a alguien que intenta aprenderlo.

http://luisquintanilla.me/2017/12/25/client-credentials-authentication-csharp/

Aquí tienes un ejemplo completo. Haga clic derecho en la solución para administrar paquetes nuget y obtener Newtonsoft y RestSharp:

using Newtonsoft.Json.Linq;
using RestSharp;
using System;


namespace TestAPI

    class Program
    
        static void Main(string[] args)
        
            String id = "xxx";
            String secret = "xxx";

            var client = new RestClient("https://xxx.xxx.com/services/api/oauth2/token");
            var request = new RestRequest(Method.POST);
            request.AddHeader("cache-control", "no-cache");
            request.AddHeader("content-type", "application/x-www-form-urlencoded");
            request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&scope=all&client_id=" + id + "&client_secret=" + secret, ParameterType.RequestBody);
            IRestResponse response = client.Execute(request);

            dynamic resp = JObject.Parse(response.Content);
            String token = resp.access_token;            

            client = new RestClient("https://xxx.xxx.com/services/api/x/users/v1/employees");
            request = new RestRequest(Method.GET);
            request.AddHeader("authorization", "Bearer " + token);
            request.AddHeader("cache-control", "no-cache");
            response = client.Execute(request);
                
    

Aquí puedes ver las comentarios y valoraciones de los lectores

Nos puedes añadir valor a nuestra información dando tu veteranía en las notas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *