9.5 KiB
SharePoint web part sample with bot framework - Secure
Summary
Web parts is a special kind of SharePoint controls that can be supported by the Bot Framework. This sample will show you how to embed a Bot Framework bot into a SharePoint web site with security consideration.
There are two parts included in this sample:
- An echo bot sample
- A web part sample
The web part sample embeds the echo bot by using a webchat. As web part code is running on client side, web chat security needs to be taken into consideration. This sample shows how to secure your conversation including:
- Use Direct Line token instead of Direct Line secret
- Tamper-proof user: for user id, generate it inside client side and detect if the client has changed the user ID and reject the change.
This demo does not include any threat models and is designed for educational purposes only. When you design a production system, threat-modelling is an important task to make sure your system is secure and provide a way to quickly identify potential source of data breaches. IETF RFC 6819 and OAuth 2.0 for Browser-Based Apps is a good starting point for threat-modelling when using OAuth 2.0.
Compatibility
⚠️ Important |
---|
Every SPFx version is only compatible with specific version(s) of Node.js. In order to be able to build this sample, please ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node. |
Refer to https://aka.ms/spfx-matrix for more information on SPFx compatibility. |
Applies to
Prerequisites
-
Node.js version 10.19 (Node.js v9.x, v11.x, and v12.x are not currently supported with SharePoint Framework development)
# determine node version node --version
Contributors
Version history
Version | Date | Comments |
---|---|---|
1.0 | Nov 10, 2020 | Initial release |
Minimal Path to Awesome
Enlist
-
Clone the repository
git clone https://github.com/pnp/sp-dev-fx-webparts.git
-
In a terminal, navigate to
sp-dev-fx-webparts
cd sp-dev-fx-webparts
-
Navigate to the folder containing this sample
cd samples cd react-bot-framework-secure
Setup bot
-
Go to
./bot
-
Install modules
npm install
-
Start the bot. You can use emulator to verify whether the bot works
npm start
-
Register connections. You can get it done by deploy your bot to Azure. Save your bot service endpoint like: "https://YOUR_BOT.azurewebsites.net". Save your AAD Id as
YOUR_APP_ID
and secret asYOUR_APP_PSW
also. -
Connect to direct line, copy one of the Secret Key values as YOUR_DIRECT_LINE_SECRET and store this for later. This is your ‘Direct Line Secret’.
-
Add
DirectLineSecret
to an.env
config file under./bot
MicrosoftAppId=YOUR_APP_ID MicrosoftAppPassword=YOUR_APP_PSW DirectLineSecret=YOUR_DIRECT_LINE_SECRET
-
Restart your bot in local or redeploy your bot with new config.
Setup web part
-
Go to
./webpart
-
Install modules
npm install
-
Start web part
gulp serve
Now web part is running locally in https://localhost:4321.
-
(Opt.) Publish the bot: follow the steps outlined in the Deploy your bot article.
-
(Opt.) Config CORS
CORS must be set on bot app service to enable SharePoint client to get resource from bot service. Follow these steps to add your workbench to bot app service CORS configuration:- Go to your azure portal
- Navigate to your bot app service, search for CORS settings
- Add https://localhost:4321 and https://<YOUR_SITE>.sharepoint.com to CORS origins
-
Config bot endpoint
Add the web part, set bot endpoint to https://localhost:4321 (local) or https://YOUR_BOT.azurewebsites.net (remote), refresh this page, then you can successfully connect bot with SharePoint.
Features
Web Chat integration with security consideration
The SharePoint component will integrate bot with react Web Chat component.
public render(): React.ReactElement<IBotFrameworkChatv4Props> {
return (
<div className={styles.botFrameworkChatv4} style={{ height: 700 }}>
<ReactWebChat directLine={directLine} styleOptions={styleSetOptions} />
</div>
);
}
Inside Web Chat, direct line will be used to connect to Bot Service. On Bot Service side, one more endpoint directline/token
will be added besides api/messages
, which will accept userId passed from client side and return back direct line token.
For production, this endpoint should also verify if the incoming request is authorized.
server.post('/directline/token', (req, res) => {
const secret = settings.parsed.DirectLineSecret;
const authorization = `Bearer ${secret}`;
const userId = 'dl_' + GetUserId((req.body || {}).user);
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
body: JSON.stringify({ user: { id: userId} }),
headers: { 'Authorization': authorization, 'Content-Type': 'application/json'}
};+
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.status(response.statusCode);
if (body) { res.send(JSON.parse(body)) }
} else {
res.status(500);
res.send('Call to retrieve token from DirectLine failed');
}
res.end();
});
});
On web part side, it will fetch direct line token from bot service side with SharePoint userId
then build up the web chat component. The UserId
should be encrypted so it won't be easy to get other user's token by bot endpoint.
useEffect(() => {
const userId = props.context.pageContext.user.loginName;
generateToken(props.botEndpoint, md5(userId)).then((token: string) => {
if (token) {
setDirectLine(createDirectLine({ token }));
}
});
}, []);
And enable "Enhanced authentication options" can help detect client user Id change then reject the change:
For how to find this option, please refer connect to direct line.
Further reading
- SharePoint Web Parts Development Basics
- Bot Framework Documentation
- Bot Basics
- Azure Bot Service Introduction
- Azure Bot Service Documentation
- Channels and Bot Connector Service
- Restify
- Using WebChat with Azure Bot Service’s Authentication
Disclaimer
THIS CODE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.