@ownid/azure-b2c
Version:
Server-side library for integrating OwnID passwordless authentication with Azure Active Directory B2C
199 lines (149 loc) • 6.47 kB
Markdown
# OwnID Azure B2C Integration
A server-side Node.js library for integrating OwnID passwordless authentication with Azure Active Directory B2C.
## Overview
This package provides a server-side solution for integrating OwnID with Azure B2C by exposing three required endpoints:
- `/setOwnIDDataByLoginId` - Store OwnID data for a user
- `/getOwnIDDataByLoginId` - Retrieve OwnID data for a user
- `/getSessionByLoginId` - Generate authentication tokens after successful OwnID authentication
## Installation
```bash
npm install @ownid/azure-b2c
```
## Prerequisites
- Node.js 16+ and npm
- Existing Azure B2C tenant
- OwnID account and application
## Server Integration
### 1. Configure Environment Variables
Create a `.env` file with your Azure and OwnID credentials:
```env
AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
AZURE_B2C_EXTENSION_APP_ID=your-extension-app-id
B2C_TENANT_NAME=yourtenant.onmicrosoft.com
OWNID_SHARED_SECRET=your-ownid-shared-secret
```
### 2. Add OwnID Router to Your Express App
```javascript
// server.js
require('dotenv').config();
const express = require('express');
const { createOwnIdAzureB2CRouter } = require('@ownid/azure-b2c');
const app = express();
const port = process.env.PORT || 3000;
// Required middleware for parsing JSON requests
app.use(express.json());
// Create and mount the OwnID router
const ownidRouter = createOwnIdAzureB2CRouter({
azureTenantId: process.env.AZURE_TENANT_ID,
azureClientId: process.env.AZURE_CLIENT_ID,
azureClientSecret: process.env.AZURE_CLIENT_SECRET,
azureB2cExtensionAppId: process.env.AZURE_B2C_EXTENSION_APP_ID,
b2cTenantName: process.env.B2C_TENANT_NAME,
ownIdSharedSecret: process.env.OWNID_SHARED_SECRET,
// disableRequestVerification: true // Uncomment to disable request verification (not recommended for production)
});
// Mount the router at /ownid
app.use('/ownid', ownidRouter);
// Start the server
app.listen(port, () => {
console.log(`Server running on port ${port}`);
console.log(`Endpoints available:`);
console.log(` POST http://localhost:${port}/ownid/setOwnIDDataByLoginId`);
console.log(` POST http://localhost:${port}/ownid/getOwnIDDataByLoginId`);
console.log(` POST http://localhost:${port}/ownid/getSessionByLoginId`);
});
```
## API Endpoints
The library creates three Express endpoints required by OwnID:
1. **Set OwnID Data** - `POST /ownid/setOwnIDDataByLoginId`
- Stores OwnID authentication data for a user identified by email address
- Request includes: `loginId` (email) and `ownIdData` (OwnID data)
2. **Get OwnID Data** - `POST /ownid/getOwnIDDataByLoginId`
- Retrieves OwnID authentication data for a user identified by email address
- Request includes: `loginId` (email)
3. **Generate Session** - `POST /ownid/getSessionByLoginId`
- Creates authentication tokens for a user after successful OwnID authentication
- Request includes: `loginId` (email)
- Returns access tokens that can be used for authentication
All endpoints include signature verification by default, requiring `ownIdSharedSecret` to be provided. Verification can be explicitly disabled with `disableRequestVerification: true`.
## Advanced Usage
### Custom Session Token Generation
You can provide your own session token generation logic, such as custom JWT creation:
```javascript
const { createOwnIdAzureB2CRouter } = require('@ownid/azure-b2c');
const jwt = require('jsonwebtoken');
// Custom session generator function
const customSessionGenerator = async (userId, email, user) => {
// Create a custom JWT token
const token = jwt.sign(
{
sub: userId,
email: email,
name: user?.displayName,
// Add custom claims as needed
},
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
return {
accessToken: token,
expiresIn: 3600,
tokenType: 'Bearer'
};
};
// Create router with custom session generator
const ownidRouter = createOwnIdAzureB2CRouter({
azureTenantId: process.env.AZURE_TENANT_ID,
azureClientId: process.env.AZURE_CLIENT_ID,
azureClientSecret: process.env.AZURE_CLIENT_SECRET,
azureB2cExtensionAppId: process.env.AZURE_B2C_EXTENSION_APP_ID,
b2cTenantName: process.env.B2C_TENANT_NAME,
ownIdSharedSecret: process.env.OWNID_SHARED_SECRET,
customSessionGenerator: customSessionGenerator
});
app.use('/ownid', ownidRouter);
```
### Direct Access to Core Services
You can directly access the core services for custom integration:
```javascript
const { OwnIDB2CAuth, OwnIDB2CUserService } = require('@ownid/azure-b2c');
// Create auth service
const auth = new OwnIDB2CAuth({
azureTenantId: process.env.AZURE_TENANT_ID,
azureClientId: process.env.AZURE_CLIENT_ID,
azureClientSecret: process.env.AZURE_CLIENT_SECRET,
azureB2cExtensionAppId: process.env.AZURE_B2C_EXTENSION_APP_ID,
b2cTenantName: process.env.B2C_TENANT_NAME,
ownIdSharedSecret: process.env.OWNID_SHARED_SECRET
});
// Create user service
const userService = new OwnIDB2CUserService(auth);
// Use the services
async function findUser(email) {
return await userService.findUserByEmail(email);
}
```
## Security
This library includes built-in request verification using HMAC signatures to ensure all incoming requests from OwnID are legitimate. By default, verification is required and you must provide `ownIdSharedSecret`.
The signature verification uses:
1. Request body
2. Request timestamp
3. Shared secret
Requests are rejected if:
- No shared secret is provided (unless explicitly disabled)
- Required headers are missing
- Signature doesn't match
- Request is too old (timestamp validation)
If you need to disable verification (not recommended for production), you can set `disableRequestVerification: true` in the configuration.
## Azure B2C Configuration
You'll need to register a dedicated application in your Azure B2C tenant and configure it with the appropriate permissions:
1. **Register an application** in your B2C tenant for OwnID integration
2. **Create a client secret** and note it down
3. **Configure API permissions**: Add `User.ReadWrite.All` permission to Microsoft Graph
4. **Grant admin consent** for the added permissions
5. **Find your B2C extension app ID** (the special b2c-extensions-app that's automatically created in your tenant)
For detailed step-by-step instructions, refer to [instructions.md](instructions.md) in the GitHub repository.
## License
MIT