react-native-azure-auth
Version:
An React Native module implements Azure AD V2.0 authentication flow
282 lines (245 loc) • 19.8 kB
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>"Accounts in any organizational directory and personal Microsoft accounts"</em> is the widest one.</li>
<li>Now you need to add <strong>Redirect URI</strong>
<ol>
<li>Select <em>Public client (mobile & 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
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": 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 | "+" | "-" | "." )
</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><intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:pathPrefix="/${applicationId}/android/callback"
android:host="${applicationId}"
android:scheme="${applicationId}" />
</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><activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:pathPrefix="/${applicationId}/android/callback"
android:host="${applicationId}"
android:scheme="${applicationId}" />
</intent-filter>
</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 <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<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 <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><key>CFBundleIdentifier</key>
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</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><key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>CFBundleURLName</key>
<string>AzureAuth</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.my-domain.native-app</string>
</array>
</dict>
</array>
</code></pre>
<blockquote>
<p><strong>Attention:</strong> The <code><string></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>