authentication-unity icon indicating copy to clipboard operation
authentication-unity copied to clipboard

Password Grant type

Open Maesla opened this issue 1 year ago • 0 comments

I was needing a password grant type because of automatic testing.

I leave it here in case anyone can use it. It works with Unity and with Unity UTF. In the middle term, it would be great to add this grant type to the whole design

    public class OAuth2PasswordGrantManager : IDisposable
    {
        private readonly string authUrl;
        private readonly string clientId;
        private readonly string clientSecret;
        private HttpClient client;

        public OAuth2PasswordGrantManager(string authUrl, string clientId, string clientSecret) :
            this(authUrl, clientId, clientSecret, new HttpClientHandler() { UseProxy = false })
        { }

        internal OAuth2PasswordGrantManager(string authUrl, string clientId, string clientSecret, HttpMessageHandler handler)
        {
            this.authUrl = authUrl;
            this.clientId = clientId;
            this.clientSecret = clientSecret;
            client = new HttpClient(handler);
        }

        public async Task<TokenResponse> GetToken(string username, string password)
        {
            //Build the payload
            Dictionary<string, string> payload = new Dictionary<string, string>
        {
            { "grant_type", "password" },
            { "username", username },
            { "password", password },
            { "client_id", clientId },
            { "client_secret", clientSecret }
        };

            return await Post(payload);
        }

        public async Task<TokenResponse> Refresh(string refreshToken)
        {
            //Build the payload
            Dictionary<string, string> payload = new Dictionary<string, string>
        {
            { "grant_type", "refresh_token" },
            { "refresh_token", refreshToken },
            { "client_id", clientId },
            { "client_secret", clientSecret }
        };

            return await Post(payload);
        }

        private async Task<TokenResponse> Post(Dictionary<string, string> payload)
        {
            HttpResponseMessage response = await client.PostAsync(authUrl, new FormUrlEncodedContent(payload));
            response.EnsureSuccessStatusCode();
            var jsonResponse = await response.Content.ReadAsStringAsync();

            return JsonUtility.FromJson<TokenResponse>(jsonResponse);
        }

        public void Dispose()
        {
            client.Dispose();
        }
    } 

    public class TokenResponse
    {
        public string AccessToken => access_token;
        public int ExpiresIn => expires_in;
        public string TokenType => token_type;
        public string RefreshToken => refresh_token;
        public string Scope => scope;

        [SerializeField]
        internal string access_token;

        [SerializeField]
        internal int expires_in;

        [SerializeField]
        internal string token_type;

        [SerializeField]
        internal string refresh_token;

        [SerializeField]
        internal string scope;
    } 

Maesla avatar May 05 '23 09:05 Maesla