previous arrowprevious arrow
next arrownext arrow
PlayPause
ArrowArrow
Shadow

Wir realisieren Ihre CAD-Projekte

im AutoCAD, Inventor, Revit und Autodesk Forge Platform

Umfeld
Wir helfen Ihnen bei der Realisierung Ihrer Projekte.

Blog.CAD-Becker.de

Beiträge zu AutoCAD und dessen Vertikalprodukte.

Tipps und Tricks, viele Neuigkeiten aus der Autodesk Welt.
4 Minuten Lesezeit (891 Worte)

Autodesk Forge - 3-legged Authentifizierung die Zweite -

Anzeige

Aktuelle Top-Angebote der Telekom, Online-Vorteile, Attraktive Prämien

​Im vorherigen Posting habe ich die ersten Schritte für die 3-legged Autorisierung erläutert. Nun möchte ich darauf eingehen wie es weiter geht.

​Wir entwickeln z.Z. ein WebService, der als Zwischenschicht zwischen der Autodesk Forge und der eigentlichen Applikationen fungiert und die Anfragen an die Forge-Platform weiterleitet und die Daten aufbereitet bereitstellt.

Dazu  dient dieser Dialog. Er soll nur die Funktionen des WebServices zum Testen bereitstellen.

 

Was geschieht nun, wenn die Schaltfläche "3-legged Autorisierung" betätigt wird?

1. Der Autorisierungsstatus wird als JObject zusammengestellt. Er beinhaltet Informationen, die wichtig sind, um auf der CallBackUrl Seite den richtigen Token zu ermitteln.
2. Die Methode "Get3LeggedToken" erhält von Forge eine URL, die zur Anmeldung an das AutoCAD Konto führt.

Passwort eintragen
E-Mail Adresse eintragen.

​Hier werden die Anmeldedaten für Ihr Autodesk-Konto eingetragen.

Autodesk.Forge.Scope[] m_Scopes = 
    new Autodesk.Forge.Scope[]
{
    Autodesk.Forge.Scope.DataRead,
    Autodesk.Forge.Scope.DataWrite,
    Autodesk.Forge.Scope.BucketCreate,
    Autodesk.Forge.Scope.BucketRead
}; 
Berechtigungen autorisieren

​In der Anforderung zum Erstellen der Anmelde URL wurden die notwendigen Rechte (SCOPES) mit übergeben. Jetzt fragt die Autodesk Konto Anmeldung ob die Anwendung autorisiert mit diesen Rechten autorisiert werden soll. 

Bitte auf Erlauben drücken.

Bis hierhin scheint alles ganz einfach zu sein. Aber jetzt wird es problematisch.

Nachdem die Anwendung autorisiert wurde, ruft Forge die CallBackURL auf und übergibt einen Code, der zum Abruf des Token benötigt wird und den Autorisierungsstatus, den wir ober definiert haben.

Das Problem ist nun, dass die CallBackURL eine Webseiten-Aufruf ist, der funktionieren muss. Auf dieser Webseite müssen die übergebenen Daten (Code und Autorisierungsstatus) verarbeitet werden und unserer Applikation zu Verfügung gestellt werden.

Ich habe ein PHP-Script geschrieben, dass diese Daten aufbereitet und in eine Textdatei schreibt. Vorherige Daten werden nicht gelöscht, da mehrere Anfragen fast gleichzeitig geschehen können, deshalb werden die Daten einfach an diese Textdatei angehängt.

<!DOCTYPE html>

<script>

</script>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Callback for Forge</title>
</head>
<body>

        <?php
			$protocol = strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') 
				=== FALSE ? 'http' : 'https';
			$host     = $_SERVER['HTTP_HOST'];
			$script   = $_SERVER['SCRIPT_NAME'];
			$params   = $_SERVER['QUERY_STRING'];
			$currentUrl = $protocol . '://' . $host . $script . '?' . $params;
       
			$myfile = fopen("Tokenfile.txt", "a") or die("Unable to open file!");
            
			$txt = "Code:" .  $_GET["code"] . ";" . $_GET["state"] . "|\r\n";
			fwrite($myfile, $txt);
        
			fclose($myfile);
			echo "Sie müssen dieses Fenster jetzt schließen, um die Anmeldung wirksam werden zu lassen";
			echo "<script>window.close();</script>";

        ?>
</body>
</html> 

 Nebenstehend finden Sie den Inhalt der Zeile, die in die Textdatei geschrieben wird.

Das Problem war, dass das PHP-Script die Daten aufbereitete aber nicht an unsere Applikation weiterleiten konnte, da es sich um ein Windows-Programm handelt. BTW: Ein AutoCAD-Plugin würde sich ebenfalls so verhalten.

Ein ASP.Net Website hätte damit kein Problem.

Im unten aufgeführten Code (Methode: Get3LeggedAuthorizeCode) wird die Textdatei heruntergeladen und verarbeitet.

Sie ermittelt die gewünschte Zeile anhand des Autorisierungsstatus und stellt mit Hilfe des Codes eine Anfrage zum Erstellen des Tokens an Forge.

Das Objekt "m_AccessToken" beinhaltet alle relevanten Daten um nun mit Forge arbeiten zu können.

Code:IrKD0V-4G2*************wqAckv54cvMPLJZ9QIS;{
"State": {
"ID": "11ef293f-e671-4197-ab0a-bc1e49b6ce89",
"Date": "08.01.2019 11:23:09",
"Company": "****************",
"CompanyName": "*************"
},
"Scopes": { "Scopes": [
0, 1, 4, 5]} 

public async static Task<CodeState> Get3LeggedAuthorizeCode(
    CP.Forge.Utilities.Settings Settings,
    JObject AuthorizeState,
    int TimeOut)
{
    JObject m_AuthorizeState = AuthorizeState;

    CP.Forge.Utilities.CPException m_Execption = null;

    CodeState m_CodeState = new CodeState(Settings);
    
    WebClient webClient = new WebClient();
    bool m_Found = false;
    DateTime m_StartTime = DateTime.Now;
    Uri m_CallBackUrl = new Uri(CP.Forge.Utilities.Credentials.CallBackUrl);

    while (m_Found == false)
    {
        System.IO.Stream m_Stream = webClient.OpenRead(
            string.Format(@"https://{0}/forge/Tokenfile.txt", m_CallBackUrl.Authority));
        System.IO.StreamReader m_TokenFileStream = new System.IO.StreamReader(m_Stream);

        string m_TokenFileContent = m_TokenFileStream.ReadToEnd();
        m_TokenFileContent = System.Web.HttpUtility.UrlDecode(m_TokenFileContent);
        m_TokenFileContent = m_TokenFileContent.Replace("\r\n", "");

        if (m_TokenFileContent.Length > 0)
        {
            string[] m_TokenFileContentSplit = m_TokenFileContent.Split('|');

            if (m_TokenFileContentSplit.Length > 0)
            {
                System.Collections.Generic.List<string> m_TokenFileList =
                    m_TokenFileContentSplit.ToList<string>();
                m_TokenFileList[m_TokenFileList.Count - 1] = "CP;CP";

                var m_Query = from string m_Line in m_TokenFileList
                              let m_Columns = m_Line.Split(';')

                              select new CodeState(Settings)
                              {
                                  Code = m_Columns[0],
                                  State = m_Columns[1].ToLower()
                              };

                var m_FoundToken = m_Query.ToList();

                m_Query = from CodeState m_CState in m_FoundToken
                          where m_CState.State == m_AuthorizeState.Property("State").ToString().Replace("\r\n", "").ToLower()
                          select m_CState;
                m_FoundToken = m_Query.ToList();

                if (m_FoundToken.Count == 1)
                {
                    m_CodeState = m_FoundToken[0];
                    string m_Code = m_CodeState.GetCode();

                    m_Request = new RestRequest(
                        Settings.BaseUrl + "/authentication/v1/gettoken",
                        Method.POST);
                    m_Request.Timeout = 5000;
                    
                    m_Request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
                    m_Request.AddParameter("client_id", CP.Forge.Utilities.Credentials.ClientID);
                    m_Request.AddParameter("client_secret", CP.Forge.Utilities.Credentials.ClientSecret);
                    m_Request.AddParameter("grant_type", "authorization_code");
                    m_Request.AddParameter("code", m_Code);
                    m_Request.AddParameter("redirect_uri", CP.Forge.Utilities.Credentials.CallBackUrl);

                    RestClient m_RestClient = new RestClient(CP.Forge.Utilities.Credentials.BASE_URL);
                    m_RestClient.Timeout = 5000;
                    IRestResponse m_Response = await m_RestClient.ExecuteTaskAsync(m_Request);
                    
                    switch (m_Response.StatusCode)
                    {
                        case HttpStatusCode.OK:
                            string m_Content = m_Response.Content;
                            string m_JsonArray = @"[" + m_Response.Content + "]";
                            Newtonsoft.Json.Linq.JArray m_TokenResponseArray = Newtonsoft.Json.Linq.JArray.Parse(m_JsonArray);
                            foreach (Newtonsoft.Json.Linq.JObject m_Token in m_TokenResponseArray.Children<Newtonsoft.Json.Linq.JObject>())
                            {
                                m_AccessToken = new AccessToken(Settings)
                                {
                                    Status = m_Response.StatusCode,
                                    AuthorizeTime = DateTime.Now,
                                    TokenType = m_Token.Property("token_type").Value.ToString(),
                                    RefreshToken = m_Token.Property("refresh_token").Value.ToString(),
                                    Scope = m_AuthorizeState.Property("Scopes")
                                };
                                int m_ExpiresIn = 0;
                                int.TryParse(m_Token.Property("expires_in").Value.ToString(), out m_ExpiresIn);
                                m_AccessToken.ExpiresIn = m_ExpiresIn;
                                await m_AccessToken.SetToken(m_Token.Property("access_token").Value.ToString());
                            }

                            m_CodeState.AccessToken = m_AccessToken;
                            break;
                    }

                    break;
                }

            }
        }
    }
    return m_CodeState;
} 

Zusätzliche Information

  • Benötigen Sie Hilfe?
    Melden Sie sich bei mir, ich helfe gerne.
Autodesk Lizenz: Lizenz Server finden
Gedanken über die Sicherheit - Teil 3 -

Ähnliche Beiträge

 

Über mich

  Dipl.-Ing.
Jürgen A. Becker
Versorgungstechnik

 

Suchen

Kalender

Warte kurz, während wir den Kalender laden

Kontakt

Jürgen A. Becker

CAD-Becker.de
Detmolder Str. 786
33699 Bielefeld
Germany
Telefon
+49 (5202) 9953808 
Mobil
+49 170 870 8679
E-Mail
Juergen.Becker(at)CAD-Becker.de