Praca z obiekatmi autoryzacyjnymi w Nintex dla Office 365 (RequestDigest, FedAuth, rtFa)
Table of Contents
Ostatnio rozpocząłem testowanie dostępnego w Nintex dla O365 RESTful API (http://help.nintex.com/en-us/sdks/sdko365/) z poziomu samych przepływów pracy (nie np. PowerShell, czy C#). Pomimo tego, że nie wszystkie metody działają poprawnie (np. zapisywanie wskazywanego przepływu jako nowy), z uwagi na fakt, iż akcja „Web Request” nie wspiera jeszcze przekazywania danych w postaci stringów binarnych i zwyczajnie wycina puste bajty (0x00), co w efekcie powoduje, że przekazywany do API plik jest niepoprawny, jednak u samych podstaw tych eksperymentów natrafiłem na inne wyzwanie. Mianowicie, w jaki sposób, z poziomu przepływu pracy tworzonego w Nintex, dostać się do wartości ciastek FedAuth i rtFa?
Czytałem artykuły, przeglądałem Stackoverflow w poszukiwaniu podobnych tematów, starając się znaleźć odpowiedź na pytanie, w jaki sposób można pobrać ciastka przy pomocy JavaScript. Traciłem już nadzieję i wówczas na trafiłem na ten cenny artykuł: Remote authentication in SharePoint Online | … And All That JS i nagle wszystko stało się jasne 🙂
Niniejszy post prezentuje sposób na uzyskanie wartości trzech obiektów, których SharePoint używa w celu uwierzytelnienia sesji:
- fedAuth cookie
- rtFa cookie
- RequestDigest token
Ciastka autoryzacyjne
Najpierw ciasteczka. By je pozyskać należy zasymulować proces logowania do tenanta. Proces ten, z poziomu przepływu Nintex, wygląda następująco:
- Najpierw należy stworzyć wiadomość żądania z treścią SAML Security Token:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action> <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <o:UsernameToken> <o:Username>[LOGIN]</o:Username> <o:Password>[PASSWORD]</o:Password> </o:UsernameToken> </o:Security> </s:Header> <s:Body> <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <a:EndpointReference> <a:Address>[TENANT ADDRESS]</a:Address> </a:EndpointReference> </wsp:AppliesTo> <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType> <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType> </t:RequestSecurityToken> </s:Body> </s:Envelope>
Należy się upewnić, że w treści XMLa nie ma żadnych, nowych linii, gdy treść będzie wklejana do akcji „Set Workflow Variable”.
Następnie należy zamienić [LOGIN] i [PASSWORD] na dane uwierzytelniające użytkownika, posiadającego wystarczające uprawnienia do wykonania docelowej operacji, np. do pracy z elementami na liście, wówczas powinien posiadać co najmniej uprawnienia odczytu do danej listy.
W przypadku, gdy dalszy proces ma na celu zapytania do REST API Nintex, wówczas użytkownik musi posiadać uprawnienia administratora zbioru witryn i koniecznie TRZEBA podać jego login, w postaci *@*.onmicrosoft.com! - Następnie należy użyć akcji „Web request” w celu wykonania zapytania POST do adresu: https://login.microsoftonline.com/extSTS.srf. Zapytanie, w Body, ma zawierać przygotowaną uprzednio wiadomość SAML Security Token:
Zapisz odpowiedź w zmiennej tekstowej. - Następny krok polega na ekstrakcji wartości Binary Security Token. Należy to wykonać, używając akcji „Query XML” używając poniższe wyrażenie regularne:
(?<=(\<wsse\:BinarySecurityToken Id\=\"Compact0\"\>))t\=(.+)(?=(\&\;p\=))
- Ponieważ w kolekcji jest tylko jeden element, należy następnie użyć akcji „Join Items in Collection” by otrzymać w efekcie sam String, którym będzie wartość Binary Security Token:
- Następnie należy wysłać token do tenant SharePoint Online, dla którego planujemy pozyskanie ciastek. Należy to zrobić korzystając z akcji „Web Request” i metody POST, wysyłając dane do adresu: https://[TENANT ADDRESS]/_forms/default.aspx?apr=1&wa=wsignin1.0, wstawiając wartość Binary Security Token w treści zapytania:
Zapisz odpowiedź z „Response headers” w zmiennej typu „Collection”.
- Wartość ciastka jest szóstym elementem tej kolekcji. Należy pobrać ją i zapisać do zmiennej typu String:
- Następnie należy wydobyć ciastka FedAuth i rtFa z ciągu tekstowego. By to zrobić, należy użyć akcji „Regular Expression”. Wydobyte wartości należy zapisać do kolekcji. Poniższe wyrażenia regularne służą do ekstrakcji wartości ciastek z tekstu:
- Następnie należy użyć akcji „Join items in collection” (znów, każda z nich ma tylko jeden element) by uzyskać wartość ciasteczek.
I już! Wartości ciasteczek fedAuth i rtFa cookies są nasze. Wygladają jak poniżej (są to stringi zakodowane algorytmem Base64):
FedAuth:
77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+VjIsMGguZnxtZW1iZXJzaGlwfDEwMDM3ZmZlOWNjMDg0ZmVAbGl2ZS5jb20sMCMuZnxtZW1iZXJzaGlwfGFkbWluQG1vZDc0Mzc0Ni5vbm1pY3Jvc29mdC5jb20sMTMxMzExMDIzNDEwMDAwMDAwLDEzMTI3NjExNjg5MDAwMDAwMCwxMzEzMTUzNDM3MTM1NjU0NjgsMC4wLjAuMCwyLDM3Nzc5NjFmLWY3YmEtNDY1Ni05ZTA5LTU5ZDk5ZjIwYmU0OSwsVjIhMTAwMzdGRkU5Q0MwODRGRSExMzEzMTEwMjM0MSw3YTQyZDM5ZC0xMGQ0LTMwMDAtYWEwZS1hNDYxYmJhYTgwODksN2E0MmQzOWQtMTBkNC0zMDAwLWFhMGUtYTQ2MWJiYWE4MDg5LGFaV1dJck5MYVFzcE9MMFV5ci9yZ1BXYlEvZmdUNDFCaHlSL1pZUXpYZnQ5Ny9Uei9ZNmovRFZtaUM3Mk80SmxkNithV1RhNVFMb2tIYndmOWZSVHRybjdUM2tqSjFtcjZ6aDlCcDNGajdUUnhJK3V3bG4vZC80M094QVBCL3NHYkUxSlNBbUV3aHgrdCtWNmNhUDUwYUtBa3kvMTROZ096R1pWQUpkbFlBVjlkRUcveXVuN2VvU1ZCazNIbFNTenNKVVY5NFNpekNFVm1ER0JyL3VxcWx0Qlp3bzR0TU5XOUtrSFdXUjcxeExBVW13TjlRQi92cFBFMEhjWFhiZ3VOZHdhVi94Tk44VllaRE9lZFNKVUQ0SitGTTdEZXRwUVJzNVVYYlNSUksxdWJ3Y3F2bVlaNElqZ2tCeW5OUHA0V2RaMnBENmgxUnZQQVF3SkVLK2lsQT09PC9TUD4=
rtFa:
7nXEhB0SmoQCQ0E2wWyjp30PoKW1AwXSpsqBXxJhXCA9QsIhkgcoMisuElVa4vEwr5gU6L+iQolckAAS5Plkqx0Xb6T9LujKOJ9gEpId4fUJRWhlwXczFIHYTNRpoS5TRRhnlriRv9CIXO6iS9WcL6L/elAifHoMkM5iq0leFXOIfRqTVT8c5b0scDkkh/3HzMqyjzwyi+mP4F3LZndD9b5zit7yZUP6xYWiHkox9JhUu2V8J/cNIqdpKLOycXHvXuKbhvpiiR1qys1E+/RPjMLxahiKgs8l3jVKp5HvVDpCSUbm6Jw6iSHiHPbK4z9RkJdj9M3ktdzVKfOIhDDmTUSqWeLB/yrZfVFa1bkv9AcpxlnmHvETlui3nn4sxHAmIAAAAA==
Form Request Digest token
Caroline Jung napisała już artykuł o tym, jak ten token otrzymać, na forum Nintex Connect (How to execute a SP2013 REST API request with Nintex Workflow ) jednak sposób działa wyłącznie dla bieżącego tenanta i użytkownika. By otrzymać token dla innego tenanta, należy użyć w zapytaniu również pobrane wcześniej ciastka autoryzacyjne. W takim wypadku proces wygląda następująco:
- Należy wysłać żądanie metodą POST korzystając z akcji „Web request” do „ContextInfo” witryny, dla której planowane jest pozyskanie tokena: https://[TENANT ADDRESS]/_api/contextinfo dodając w jako nagłówek żądania wartości ciastek, w postaci poniższego stringa:
FedAuth={Variable:FedAuth_Cookie};rtFa={Variable:rtFa_Cookie}
W polu „Body” można wstawić dowolny tekst. Ważne, by nie było puste.
Zapisz odpowiedź (Response Content) do zmiennej tekstowej.
- Potem, jak napisała Caroline, należy wydobyć wartość tokena z otrzymanego XMLa. W tym celu należy użyć poniższą kwerendę xPath:
//*[local-name()='FormDigestValue']
i wynik zapisać w zmiennej tekstowej:
Voilla! Teraz mamy również wartość tokena Form Request Digest. Powinna być podobna do tej:
0x0E07BB747A8A51DF739E090592B3AADB293A16E73CE9C9D6451B5478B1EEA7514CF7527C890EAB40539C8A49E38C8C92AF73257A3972531E0F566086E12AC01D,09 Feb 2017 08:26:47 -0000
Gdzie można użyć te obiekty?
Mogą być użyte w szczególności do autoryzacji żądań w przypadku zapytań do innych tenatów, z poziomu przepływu pracy na Twoim tenancie (dyby z jakiegoś powodu niemożliwe było użycie jednej z akcji oznaczonych hasłem „Office 365”). Lub właśnie, by wysyłać zapytania do metod Nintex O365 Workflow REST API z poziomu innego workflowu. Ważne jest, by w każdym z tych przypadków, w nagłówku żądania wstawić poniższy tekst, zawierający w sobie wartość obu ciastek autoryzacyjnych:
FedAuth={Variable:FedAuth_Cookie};rtFa={Variable:rtFa_Cookie}
Mam nadzieję, że powyższe informacje będą pomocne 🙂