Search Unity

OpenId authentication in Unity

Discussion in 'Multiplayer' started by tkEpilog, Jun 28, 2021.

  1. tkEpilog

    tkEpilog

    Joined:
    Apr 20, 2021
    Posts:
    1
    Hello,
    I would like to use Keycloak (Keycloak), to login to my Unity3D application. Keycloak uses OpenId, and I can't seem to find any example of using OpenId in Unity. I am new to using OpenId and don't really know how to implement this, so any help would be appreciated.
     
  2. NikosPetr

    NikosPetr

    Joined:
    Nov 15, 2016
    Posts:
    4
    Bump, as I need help with the same problem.
     
  3. Harpaceas

    Harpaceas

    Joined:
    Feb 15, 2021
    Posts:
    4
    Bump, I can get the authorization code and access token by a keycloak endpoint ONLY when I already have the browser opened and already did the login, otherwise the code fails to get the authorization code.

    so considering I implement this logic at the application start, I have to run it 2 times to get code and then the token.

    I just use rest APIs because I can not find an understandable keycloak library to use for desktop / native applications.

    this is my code:
    Code (CSharp):
    1. public static async  Task<string>  GetTokenAsync()
    2.     {
    3.  
    4.         string redirectURI = string.Format("http://{0}:{1}/", "localhost", GetRandomUnusedPort());
    5.         string RedirectURIWithoutLastSlash = redirectURI.TrimEnd('/');
    6.  
    7.  
    8.         string code = await GetCodeForAuthentication(redirectURI, RedirectURIWithoutLastSlash);
    9.  
    10.         UnityWebRequest request = new UnityWebRequest();
    11.         request.url = $"https://tokenEndpoint.../protocol/openid-connect/token";
    12.  
    13.         request.method = UnityWebRequest.kHttpVerbPOST;
    14.         request.downloadHandler = new DownloadHandlerBuffer();
    15.        
    16.  
    17.  
    18.         request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    19.  
    20.         string postData = "";
    21.  
    22.         Dictionary<string, string> postParameters = new Dictionary<string, string>() /
    23.             {
    24.                 {"grant_type", "authorization_code"},
    25.                 {"code", code},
    26.                 {"client_id", "myID"},
    27.                 {"client_secret", "mySECRET"},
    28.                 {"redirect_uri", RedirectURIWithoutLastSlash }
    29.             };
    30.  
    31.         foreach (string key in postParameters.Keys)
    32.             postData += UnityWebRequest.EscapeURL(key) + "=" + UnityWebRequest.EscapeURL(postParameters[key]) + "&";
    33.  
    34.         byte[] data = Encoding.ASCII.GetBytes(postData);
    35.  
    36.         request.uploadHandler = new UploadHandlerRaw(data) ;
    37.  
    38.         request.timeout = 60;
    39.  
    40.         request.SendWebRequest();
    41.  
    42.         while (!request.isDone)
    43.         {
    44.             Debug.Log(request.downloadProgress);
    45.         }
    46.  
    47.         Debug.Log("text by server is: " + request.downloadHandler.text);
    48.  
    49.         TokenClass token = JsonUtility.FromJson<TokenClass>(request.downloadHandler.text);
    50.  
    51.         access_token = token.access_token;
    52.  
    53.         tokenInfo = token;
    54.         Debug.Log("access token is: " + access_token);
    55.  
    56.         return access_token;
    57.     }
    58.  
    59.     private static async Task<string> GetCodeForAuthentication(string redirectURI, string RedirectURIWithoutLastSlash)
    60.     {
    61.  
    62.      
    63.  
    64.         string code = null;
    65.  
    66.         HttpListener http = new HttpListener();
    67.         http.Prefixes.Add(redirectURI);
    68.         http.Start();
    69.  
    70.  
    71.  
    72.         string authorizationRequest = $"https://authCode Endpoint.../protocol/openid-connect/auth?client_id=myID&response_type=code&response_mode=query&scope=profile&redirect_uri={RedirectURIWithoutLastSlash}";
    73.  
    74.         // Opens request in the browser.
    75.         Process web_Login_Process = new Process();
    76.         web_Login_Process.StartInfo.FileName = GetSystemDefaultBrowser();
    77.         web_Login_Process.StartInfo.Arguments = authorizationRequest;
    78.         web_Login_Process.Start();
    79.  
    80.  
    81.             try
    82.             {
    83.              
    84.                 var context = await http.GetContextAsync();
    85.                 var response = context.Response;
    86.  
    87.                 var html = "<html><head><meta http-equiv='refresh' content='10;url=https://localhost'></head><body>Please return to the Digital Twin.</body></html>";
    88.  
    89.  
    90.                 string responseString = string.Format(html);
    91.                 var buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
    92.                 response.ContentLength64 = buffer.Length;
    93.                 var responseOutput = response.OutputStream;
    94.                 Task responseTask = responseOutput.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
    95.                 {
    96.                     responseOutput.Close();
    97.                     http.Stop();
    98.                     Console.WriteLine("HTTP server stopped.");
    99.                 });
    100.            
    101.            
    102.             // Checks for errors.
    103.             if (context.Request.QueryString.Get("error") != null)
    104.                 {
    105.                     string debug = context.Request.QueryString.Get("error");
    106.  
    107.                 }
    108.                 if (context.Request.QueryString.Get("code") == null
    109.                     || context.Request.QueryString.Get("state") == null)
    110.                 {
    111.  
    112.                     var debug = context.Request.QueryString;
    113.  
    114.                     var debug3 = context.Request.RawUrl;
    115.  
    116.  
    117.                 }
    118.                 // extracts the code
    119.                 code = context.Request.QueryString.Get("code");
    120.  
    121.                 string tryCode = context.Request.QueryString["code"];
    122.  
    123.                 Debug.Log("code is: " + code);
    124.  
    125.                
    126.  
    127.             }
    128.             catch (Exception ex)
    129.             {
    130.                 string g = ex.Message;
    131.             }
    132.  
    133.         return code;
    134.     }