0

I'm developing a desktop application with Unity and I need to check if the user can log in Outlook to have access to my app.

So, I'm following this process from Microsoft docs and I'm trying to figure out how I can open Outlook API login page and send to my app the authorization code and then get the access-token to finally obtained information about the user. I tried several ways but without success.

First, I tried to obtain a kind of AuthenticationContext like We can use in general C# .NET Application by importing some .dlls but It seems that this solution is just a dream.

Then, I tried this functions I found, but the issue is that Outlook API, like all Microsoft Authentication API (I guess), needs a redirect_uri to send the code and the access-token. If I can get this authorization's code, I think that I could use the functions I found to do what I need. I tried to set a website with a PHP script as redirect_link to get the code and at the same time, do a request to get it. But even if I try to get it through this script with a UnityWebRequest it's not working and It's really an ugly way to do it ^^'

Is there a way to open the Outlook "authorize" page and wait for a response ? Like if I could put the redirect_uri as my desktop application?

I need your help! And is there a better way to do it than mine?

Thanks !

UPDATE : Here is my C# code

private IEnumarator ConnectOutlook()
{
    string client_ID = "client-id";
    string redirect_uri = "link of my PHP script";
    string response_type = "code";
    string url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + client_ID + "&redirect_uri=" + redirect_uri + "&response_type=" + response_type + "&scope=openid";
    Application.OpenURL(url);
    string resultCode = null;
    StartCoroutine(GetAuthorization((code) => resultCode = code));
    yield return new WaitUntil(() => resultCode != null);
StartCoroutine(GetAccessToken(resultCode));
    }

private static IEnumerator GetAuthorization(Action<string> result)
{
    Dictionary<string, string> content = new Dictionary<string, string>();

    content.Add("action", "GetCode");
    UnityWebRequest www = UnityWebRequest.Post("link of my PHP Script", content);
    //Send request
    yield return www.Send();

    yield return new WaitUntil(() => www.downloadHandler.text != "");
    if (!www.isNetworkError)
    {
        string resultContent = www.downloadHandler.text;
        Debug.Log(resultContent);
         result(resultContent);
    }
    else
    {
        //Return null
        result("");
    }
}

private static IEnumerator GetAccessToken(string code)
    {

        Dictionary<string, string> content = new Dictionary<string, string>();
        //Fill key and value

        content.Add("client_id", "client-id");
        content.Add("client_secret", "client_secret");
        content.Add("code", code);
        content.Add("redirect_uri", "link of my PHP Script");
        content.Add("grant_type", "authorization_code");

        UnityWebRequest www = UnityWebRequest.Post("https://login.microsoftonline.com/common/oauth2/v2.0/token", content);
        //Send request
        yield return www.Send();

        if (!www.isNetworkError)
        {
            string resultContent = www.downloadHandler.text;
            TokenClassName json = JsonUtility.FromJson<TokenClassName>(resultContent);

            //Return result
            Debug.Log(json.access_token);
        }
        else
        {
            //Return null
            result("");
        }
    }

public class TokenClassName
{
    public string access_token;
}

And here is my PHP Script (Please don't forget I'm trying to not use this script) :

<?php
    $code = "";
  // Here I get the code when Outlook API is redirecting after log in
  if (isset($_GET['code'])) {
    //Assign the code 
        $code = $_GET['code'];
  }
  elseif (isset($_GET['error'])) {
    exit('ERROR: '.$_GET['error'].' - '.$_GET['error_description']);
  }

  //Here I try to return the assigned code
  if ($_POST["action"] == "GetCode"){
    echo $_GET['code'];
  } 
?>

I'm really looking for a way to disable the redirection to my script. The best should be to use an "await" for a response like in .NET UWP with AuthorizationContext and the way explained HERE

  • Post the `UnityWebRequest` code that isn't working – Programmer Sep 14 '17 at 20:54
  • I did it, but for me, It's not an `UnityWebRequest` issue. I'm trying to find a way to get the authorization code after log in from Outlook by "awaiting" the code and without redirect it to a link or, in this case, my ugly/desperate PHP script – Killian Richard Sep 14 '17 at 21:33
  • Maybe I forgot something about the possibilities of redirect_uri and I just don't understand how to set it up for a desktop application – Killian Richard Sep 14 '17 at 21:41
  • Maybe I don't get your problem. Shouldn't the token be stored in `json.access_token` variable? – Programmer Sep 14 '17 at 23:25
  • Yes, but my problem is how to get the authorization code I need to get the access token without redirection to a website. – Killian Richard Sep 15 '17 at 06:26

1 Answers1

0

You need to use a loopback redirection URL. For example http://localhost:7000/. Just run a listen server inside Unity that will listen to any call of http://localhost:7000/ URL. Like

TcpListener server = new TcpListener ("http://localhost", 7000); 

You can also have some random session parameters to ensure http://localhost:7000 is called from the propper session that just started.

Check this git-hub repo with examples: https://github.com/zizul/OAuth2.0-Unity/blob/master/Assets/OAuthClient.cs

I've not testes the code. I will update this post after I check it. But it looks like it should work.

Sergey
  • 43
  • 6