Skip to content

Commit

Permalink
doc update (microsoft#2347)
Browse files Browse the repository at this point in the history
* update docs to reflect the latest related to skills architecture

* Update architecture.md

Update architecture doc

* Update skillauthentication.md

update authentication doc

* Update skillauthentication.md

update whitelist docs
  • Loading branch information
lzc850612 authored and ryanisgrig committed Sep 12, 2019
1 parent aec3ad2 commit 7238826
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 42 deletions.
35 changes: 2 additions & 33 deletions docs/_docs/reference/skills/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,15 @@ All communication between a Virtual Assistant and a Skill is performed through a

The `SkillManifest` provides the endpoint for the SkillDialog to communicate with along with action and slot information. Slots are optional and a way to pass parameters to a Skill.

A `skill/begin` event is sent at the beginning of each Skill Dialog and the end of a Skill Dialog is marked by the sending of a `endOfConversation` event. This event contains a `SkillContext` object that contains matched Slot information, if the Virtual Assistant has populated matching data into it's SkillContext object then it's retrieved and passed across to the Skill.

For example, if there is a `Location` data item in Virtual Assistant SkillContext object and the Skill being invoked has a `Location` slot it will be matched and passed.

An example of a `skill/begin` event is shown below:

```json
{
"type": "event",
"channelId": "test",
"from": {
"id": "user1",
"name": "User1"
},
"conversation": {
"id": "Conversation1"
},
"recipient": {
"id": "bot",
"name": "Bot"
},
"value": {
"param1": "TEST",
"param2": "TEST2"
},
"name": "skill/begin"
}
```

This dialog remains active on the Virtual Assistant's `DialogStack`, ensuring that subsequent utterances are routed to your Skill.

When an `EndOfConversation` event is sent from the Skill, it tears down the `SkillDialog` and returns control back to the Virtual Assistant.
When a Skill wants to terminate an ongoing dialog, it sends back an Activity with `Handoff` type to signal the completion of the current dialog.

See the [SkillAuthentication]({{site.baseurl}}/reference/skills/skillauthentication) section for information on how Bot->Skill invocation is secured.

## Skill Middleware

The `SkillMiddleware` is used by each Skill and is configured automatically if you use the Skill Template.

The middleware consumes the `skill/begin` event and populates SkillContext on the Skill side making slots available.
The middleware consumes the `skill/cancelallskilldialogs` event, when the Skill receives it it clears out the active dialog stack on that active Skill. This is useful in interruptions - i.e. if a user asks to cancel, a Virtual Assistant can send this event to the Skill and cancel the active dialog.

## Interrupting Active Skills

Expand Down
61 changes: 52 additions & 9 deletions docs/_docs/reference/skills/skillauthentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,26 @@ order: 4

# {{ page.title }}

A skill needs to be able to validate the request coming from another bot (Virtual Assistant). It needs to verify that the request comes from a properly registered bot service, and that the request was intended for the skill. To achieve this, we use AAD token mechanism
A Skill needs to be able to authenticate the request coming from another bot (Virtual Assistant). The Skill model requires two levels of Authentication:

## JWT Authentication

The Virtual Assistant needs to include an Authorization header in the request.

This is needed as a Skill needs to verify that the request comes from a properly registered bot service, and that the request was intended for the skill. Because every bot service is a Microsoft app, we can leverage AAD to obtain JWT token as well as verification

![Skill Authentication Flow]({{site.baseurl}}/assets/images/virtualassistant-skillauthentication.png)

Between Virtual Assistant and skill bot, we'll use AAD as the authority to generate and validate token. The token will be a JWT token. Virtual Assistant will use this information to request a JWT token:
1. Microsoft app id - this will become the source appid claim in the token
1. Microsoft app id - this will become the source appid claim in the token
2. Microsoft app password
3. Skill bot's Microsoft app id - this will become the audience claim in the token

The JWT token will be a 'bearer' token so it'll be part of the Authorization header.

When skill bot receives a request, it looks at the Authorization header to retrieve the token. Then it will rely on AAD to decrypt & validate the JWT token. Right now the skill will only verify if the audience claim is the skill's Microsoft app id. If the audience claim verification passes, then the authentication succeeds and the request moves forward into the skill bot for further processing.

By default, a skill that's created out of a Skill Template doesn't enable authentication. Any bot can send a request to a skill bot without having to retrieve a token and the skill bot would be able to handle that request. With the support of Microsoft.Bot.Builder.Skills, it's very easy to enable authentication. You just need to add one line of code in your skill bot's startup.cs class:

```csharp
services.AddSingleton<IAuthenticationProvider, MsJWTAuthenticationProvider>();
```

With the registration of `IAuthenticationProvider` to be `MsJWTAuthenticationProvider` which is a default implementation provided by the package, the authentication is enabled on the skill bot. Any request that comes to this skill will go through the authentication so the skill is well protected.
By default, a skill that's created out of a Skill Template enables JWT authentication.

On the Virtual Assistant side, we use the SkillDialog to dispatch requests to the skills. To enable Virtual Assistant to obtain proper JWT token to send a request to skill, you need to have these lines of code when you create the SkillDialog instances:

Expand All @@ -37,3 +37,46 @@ skillDialogs.Add(new SkillDialog(skill, credentials, telemetryClient, userState,
```

The `MicrosoftAppCredentialsEx` class provided within the Microsoft.Bot.Builder.Skills package is the central place to manage the information needed for the skill to obtain the AAD token. Once you pass this into the SkillDialog, the SkillDialog will be able to use it to properly retrieve the AAD token. This behavior is the default behavior if you create a Virtual Assistant out of the Virtual Assistant Template VSIX.

## Whitelist Authentication

After the JWT token is verified, the SKill bot needs to verify if the request comes from a bot that's previously included in a whitelist. A Skill needs to have knowledge of it's callers and give permissions to that bot explicitly instead of any bot that could call the Skill. This level of authorization is enabled by default as well, making sure a Skill is well protected from public access. Developers need to do the following to implement the Whitelist mechanism:

Declare a class `WhiteListAuthProvider` in the bot service project that implements the interface `IWhitelistAuthenticationProvider`

```csharp
public HashSet<string> AppsWhitelist
{
get
{
return new HashSet<string>
{
// add AppIds of Virtual Assistant here
};
}
}
```

By adding the Microsoft App id of the Virtual Assistant that's calling the Skill into the property AppsWhitelist, you are allowing the bot that's associated with that app id to invoke your skill.

In `Startup.cs`, register a singleton of the interface with this class

```csharp
// Register WhiteListAuthProvider
services.AddSingleton<IWhitelistAuthenticationProvider, WhiteListAuthProvider>();
```

In `BotController.cs` (derived from the `SkillController`, add the class as a new parameter to the constructor

```csharp
public BotController(
IBot bot,
BotSettingsBase botSettings,
IBotFrameworkHttpAdapter botFrameworkHttpAdapter,
SkillWebSocketAdapter skillWebSocketAdapter,
IWhitelistAuthenticationProvider whitelistAuthenticationProvider)
: base(bot, botSettings, botFrameworkHttpAdapter, skillWebSocketAdapter, whitelistAuthenticationProvider)
{}
```

With all these changes in place, you're enabling your Skill to allow bots to invoke it as long as the bot's Microsoft App id is included in the whitelist.

0 comments on commit 7238826

Please sign in to comment.