UNPKG

react-native-azure-auth

Version:

An React Native module implements Azure AD V2.0 authentication flow

282 lines (245 loc) 19.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Home - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Auth.html">Auth</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.acquireTokenSilent">acquireTokenSilent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.clearPersistenCache">clearPersistenCache</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.exchange">exchange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.loginUrl">loginUrl</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.logoutUrl">logoutUrl</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.msGraphRequest">msGraphRequest</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Auth.html#.refreshTokens">refreshTokens</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="AzureAuth.html">AzureAuth</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="BaseError.html">BaseError</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Client.html">Client</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.AccessTokenItem.html">AccessTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.BaseTokenItem.html">BaseTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.RefreshTokenItem.html">RefreshTokenItem</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.Scope.html">Scope</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="TokenCache.TokenCache.html">TokenCache</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="WebAuth.html">WebAuth</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="WebAuth.html#.authorize">authorize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="WebAuth.html#.clearSession">clearSession</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getAllUserTokenKeys">getAllUserTokenKeys</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isIntersects">isIntersects</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isSubsetOf">isSubsetOf</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#request">request</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#serializeParams">serializeParams</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#validate">validate</a></span></li> </nav> <div id="main"> <section class="readme"> <article><h1>react-native-azure-auth</h1> <p><a href="https://github.com/pickhardt/maintainers-wanted"><img src="https://img.shields.io/badge/maintainers-wanted-red.svg" alt="Maintainers Wanted"></a> <a href="https://circleci.com/gh/vmurin/react-native-azure-auth"><img src="https://circleci.com/gh/vmurin/react-native-azure-auth.svg?style=svg" alt="CircleCI"></a></p> <p>React Native library implementing Azure AD OAuth2 API</p> <p>The library uses the latest <strong>V2.0</strong> version of the <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare">Azure AD endponts</a> and provides token cache functionality. <code>react-native-azure-auth</code> implements authentication flow using <code>fetch</code> API and native components. The OpenID connect and <code>authorization_code</code> grant are implemented.</p> <p>JS Docs can be accesed under <a href="https:%5C/%5C/vmurin.github.io/react-native-azure-auth/">https://vmurin.github.io/react-native-azure-auth/</a></p> <h2>Maintainers/Developers wanted</h2> <p><strong>ATTENTION!</strong> react-native-azure-auth project is looking for maintainers and contributors! For various reasons, I can only keep maintaining this project as far as dependency bumps and publishing. As for new features and the bug/issue support, these will require other maintainers/contributors.</p> <p>If that's you - please feel free to ping me and I will add you to contributors of this repo with according rights.</p> <h2>Installation</h2> <p>Install <code>react-native-azure-auth</code> using <a href="https://www.npmjs.com">npm</a></p> <pre class="prettyprint source lang-bash"><code>npm install react-native-azure-auth --save </code></pre> <p>Or via <a href="https://yarnpkg.com/">yarn</a> (recommended)</p> <pre class="prettyprint source lang-bash"><code>yarn add react-native-azure-auth </code></pre> <p>Then you need to link the native modules in <code>react-native-azure-auth</code> and used AsyncStorage. Please check the <a href="https://reactnative.dev/docs/linking-libraries-ios">link</a>.</p> <p>If you have used library before, it could be needed also to unlink the community version of AsyncStorage too.</p> <p><strong>Note:</strong> If you are using <a href="https://github.com/react-native-community/cli/blob/master/docs/autolinking.md">autolinking</a> please be aware of caution to unlink the libraries in the autolinking docs. Especially if you are encountered the problem like issue <a href="https://github.com/vmurin/react-native-azure-auth/issues/98">#98</a></p> <h3>App Registration</h3> <p>First, you will need to register your application with Microsoft Azure Portal. This will give you an Application ID for your application, as well as enable it to receive tokens.</p> <ol> <li>Sign in to the <a href="https://portal.azure.com">Microsoft Azure Portal</a>.</li> <li>First you need to find the <strong>App Registration Service</strong>. You could just type in the service name in the search bar on the middle top of the window and select it or do like following: <ol> <li>Click on <strong>All services</strong> in the left panel</li> <li>Then select from the shown in bold categories the <strong>Identity</strong></li> <li>Click on the star sign near the <em>App registration</em> service name to add it to favorites</li> <li>Now you can easily access the service using the left portal panel</li> </ol> </li> <li>After selecting <em>App registration</em> service click <strong>New registration</strong></li> <li>Enter a friendly name for the application</li> <li>Select account type that should be supported by your app. The default choice <em>&quot;Accounts in any organizational directory and personal Microsoft accounts&quot;</em> is the widest one.</li> <li>Now you need to add <strong>Redirect URI</strong> <ol> <li>Select <em>Public client (mobile &amp; desktop)</em> from dropdown</li> <li>Type in the URI. See the URI format in the section below.</li> </ol> </li> <li>Click <strong>Register</strong> to create the app registration record.</li> <li>Find the <em>Application (client) ID</em> value in <strong>Overview</strong> section, copy and save the value in a safe location.</li> <li>You don't need to set <em>API Permissions</em>. It is meant for admin consent only.</li> <li>Now select <strong>Authentication</strong> from the left menu</li> <li>Select checkbox <strong>ID tokens</strong>[^implicitgrantnote] in the <em>Implicit grant</em> section - it is needed for OpenID Connect. The library will still use authorization grant and not implicit.</li> <li>Click <strong>Save</strong> button above to save changes.</li> </ol> <p>[^implicitgrantnote]: This checkbox <a href="https://github.com/vmurin/react-native-azure-auth/issues/174">might not exist (anymore)</a>.</p> <pre><code>If this is the case, go to **Manifest** and set the following values to true: ```json &quot;oauth2AllowIdTokenImplicitFlow&quot;: true, &quot;oauth2AllowImplicitFlow&quot;: true, ``` </code></pre> <h4>Callback URL(s)</h4> <p>Callback URLs are the URIs that Azure AD invokes after the authentication process. Azure routes your application back to this URI and appends additional parameters to it, including a token. Since callback URLs can be manipulated, you will need to add your application's URL to your apps's registered <strong>Redirect-URIs</strong>. This will enable Azure to recognize these URLs as valid. If omitted, authentication will not be successful.</p> <h5>iOS - default redirect URI structure</h5> <pre class="prettyprint source lang-text"><code>{YOUR_BUNDLE_IDENTIFIER}://{YOUR_BUNDLE_IDENTIFIER}/ios/callback </code></pre> <h5>Android - default redirect URI structure</h5> <pre class="prettyprint source lang-text"><code>{YOUR_APP_PACKAGE_NAME}://{YOUR_APP_PACKAGE_NAME}/android/callback </code></pre> <p><strong>Note 1:</strong> Make sure to replace {YOUR_BUNDLE_IDENTIFIER} and {YOUR_APP_PACKAGE_NAME} with the actual values for your application.</p> <p><strong>Note 2:</strong> Be aware of allowed characters for the scheme part of URI. According to RFC 2396 (Section 3.1):</p> <pre class="prettyprint source lang-text"><code>scheme = alpha *( alpha | digit | &quot;+&quot; | &quot;-&quot; | &quot;.&quot; ) </code></pre> <p>As you can see, allowed in identifier and package name underscore (<code>_</code>) character is NOT allowed in the URI scheme!</p> <h5>Custom redirect URI</h5> <p>You are free to use any custom URI taking into account restrictions stated above. Just add <code>redirectUri:</code> parameter to the <code>AzureAuth</code> initialization call. See the <a href="https://vmurin.github.io/react-native-azure-auth/AzureAuth.html">docs</a> and <a href="#usage">Usage</a> section.</p> <h5>Single tenant app registration</h5> <p>To be able to use this app type you should add <code>tenant</code> property in the <code>AzureAuth</code> init options like this:</p> <pre class="prettyprint source lang-javascript"><code>const azureAuth = new AzureAuth({ clientId: YOUR_CLIENT_ID, tenant: 'XXXXXXXX-YYYY-ZZZZ-AAAA-BBBBBBBBBBBB', // your app tenant ID }); </code></pre> <h3>App Configuration</h3> <h4>Android config</h4> <p>In the file <code>android/app/src/main/AndroidManifest.xml</code> you must make sure the <strong>MainActivity</strong> of the app has a <strong>launchMode</strong> value of <code>singleTask</code> and that it has the following intent filter:</p> <pre class="prettyprint source lang-xml"><code>&lt;intent-filter> &lt;action android:name=&quot;android.intent.action.VIEW&quot; /> &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /> &lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; /> &lt;data android:pathPrefix=&quot;/${applicationId}/android/callback&quot; android:host=&quot;${applicationId}&quot; android:scheme=&quot;${applicationId}&quot; /> &lt;/intent-filter> </code></pre> <p>The <code>applicationId</code> here should be the same as your app <strong>package name</strong>, and not the ID from MS App Portal.</p> <p>You would have the following <strong>MainActivity</strong> configuration:</p> <pre class="prettyprint source lang-xml"><code>&lt;activity android:name=&quot;.MainActivity&quot; android:label=&quot;@string/app_name&quot; android:launchMode=&quot;singleTask&quot; android:configChanges=&quot;keyboard|keyboardHidden|orientation|screenSize&quot; android:windowSoftInputMode=&quot;adjustResize&quot;> &lt;intent-filter> &lt;action android:name=&quot;android.intent.action.MAIN&quot; /> &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /> &lt;/intent-filter> &lt;intent-filter> &lt;action android:name=&quot;android.intent.action.VIEW&quot; /> &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /> &lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; /> &lt;data android:pathPrefix=&quot;/${applicationId}/android/callback&quot; android:host=&quot;${applicationId}&quot; android:scheme=&quot;${applicationId}&quot; /> &lt;/intent-filter> &lt;/activity> </code></pre> <blockquote> <p>For more info please read <a href="https://facebook.github.io/react-native/docs/linking.html">react native docs</a></p> </blockquote> <h4>iOS config</h4> <p>Inside the <code>ios</code> folder find the file <code>AppDelegate.[swift|m]</code> add the following to it</p> <pre class="prettyprint source lang-objc"><code>// iOS 9.x or newer #import &lt;React/RCTLinkingManager.h> - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary&lt;UIApplicationOpenURLOptionsKey,id> *)options { return [RCTLinkingManager application:application openURL:url options:options]; } </code></pre> <p>If you're targeting iOS 8.x or older, you can use the following code instead:</p> <pre class="prettyprint source lang-objc"><code>// iOS 8.x or older #import &lt;React/RCTLinkingManager.h> - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; } </code></pre> <p>Inside the <code>ios</code> folder open the <code>Info.plist</code> and locate the value for <code>CFBundleIdentifier</code>, e.g.</p> <pre class="prettyprint source lang-xml"><code>&lt;key>CFBundleIdentifier&lt;/key> &lt;string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)&lt;/string> </code></pre> <blockquote> <p>The value <code>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</code> is the default for apps created with React Native CLI, you may have a different value.</p> <p>It is advisable to replace it with your own meaningfull ID in reverse DNS format. e.g. <em>com.my-domain.native-app</em></p> </blockquote> <p>and then register a URL type entry using the value of <code>CFBundleIdentifier</code> as the value of <code>CFBundleURLSchemes</code></p> <pre class="prettyprint source lang-xml"><code>&lt;key>CFBundleURLTypes&lt;/key> &lt;array> &lt;dict> &lt;key>CFBundleTypeRole&lt;/key> &lt;string>None&lt;/string> &lt;key>CFBundleURLName&lt;/key> &lt;string>AzureAuth&lt;/string> &lt;key>CFBundleURLSchemes&lt;/key> &lt;array> &lt;string>com.my-domain.native-app&lt;/string> &lt;/array> &lt;/dict> &lt;/array> </code></pre> <blockquote> <p><strong>Attention:</strong> The <code>&lt;string&gt;</code> value for <code>CFBundleURLSchemes</code> key MUST be the literal value of the Bundle Identifier with NO $-variables. In the example above the string <code>com.my-domain.native-app</code> represents <em>your</em> Bundle Identifier.</p> </blockquote> <p>For more info please read <a href="https://facebook.github.io/react-native/docs/linking.html">react native docs</a></p> <h2>Usage</h2> <pre class="prettyprint source lang-js"><code>import AzureAuth from 'react-native-azure-auth'; const azureAuth = new AzureAuth({ clientId: 'YOUR_CLIENT_ID' }); </code></pre> <h3>Authorization with user interaction</h3> <pre class="prettyprint source lang-js"><code> try { let tokens = await azureAuth.webAuth.authorize({scope: 'openid profile User.Read Mail.Read' }) this.setState({ accessToken: tokens.accessToken }); let info = await azureAuth.auth.msGraphRequest({token: tokens.accessToken, path: '/me'}) this.setState({ user: info.displayName, userId: tokens.userId }) } catch (error) { console.log(error) } </code></pre> <h3>Silent authorization</h3> <pre class="prettyprint source lang-js"><code> try { // Try to get cached token or refresh an expired ones let tokens = await azureAuth.auth.acquireTokenSilent({scope: 'Mail.Read', userId: this.state.userId}) if (!tokens) { // No cached tokens or the requested scope defines new not yet consented permissions // Open a window for user interaction tokens = await azureAuth.webAuth.authorize({scope: 'Mail.Read'}) } let mails = await azureAuth.auth.msGraphRequest({token: tokens.accessToken, path: '/me/mailFolders/Inbox/messages'}) } catch (error) { console.log(error) } </code></pre> <h3>Usage example</h3> <p>You can consult a tiny sample project <a href="https://github.com/vmurin/react-native-azure-auth-sample">react-native-azure-auth-sample</a> for usage example</p> <h2>Issue Reporting</h2> <p>If you have found a bug or if you have a feature request, please report them at this repository issues section. Please take a little time and use search functionality of the issue tracker before posting a new issue, you can find some usefull infos in already closed issues. Please also do not report security vulnerabilities on the public GitHub issue tracker.</p> <h2>Author</h2> <p><a href="https://github.com/vmurin">Vlad Murin</a></p> <h2>Credits</h2> <p>This project was originally inspired by <a href="https://github.com/auth0/react-native-auth0">https://github.com/auth0/react-native-auth0</a></p> <h2>License</h2> <p>This project is licensed under the MIT license. See the <a href="LICENSE">LICENSE</a> file for more info.</p></article> </section> </div> <br class="clear"> <footer> Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a> on Wed Jun 25 2025 10:35:11 GMT+0200 (Central European Summer Time) using the Minami theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>