Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Adding ClaimsIdentity and ConnectorClient to the services collection - #356

Merged
RamjotSingh merged 2 commits into
masterfrom
ramjsing/master-ConnectorClientInServices
Mar 30, 2018
Merged

Adding ClaimsIdentity and ConnectorClient to the services collection#356
RamjotSingh merged 2 commits into
masterfrom
ramjsing/master-ConnectorClientInServices

Conversation

@RamjotSingh

Copy link
Copy Markdown
Member

Adding ClaimsIdentity and ConnectorClient to the services collection and removing BotFrameworkTurnContext.

Why? - This means extensions like Teams no longer have to explicitly depend on BotFrameworkAdapter but instead can depend on presence of IIdentity for getting BotAppId and IConnectorClient to get ConnectorClient in the Middleware. Or new clients can be created using ICredentialProvider + IIdentity. Since both IIdentity and IConnectorClient are outside BotFrameworkAdapter the dependency is optional now.
Also this allows developers to call ConnectorClient methods directly which were otherwise hidden away.

What this does not solve? BotFrameworkAdapter is still special cased as it requires more info when compared to base BotAdapter and thus does not follow BotAdapter in few specific cases. Will try to fix this in a different PR (or atleast part of it).

@RamjotSingh RamjotSingh added this to the 3/26 milestone Mar 27, 2018

@drub0y drub0y left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I like this approach a lot. I especially 💗 the connector client being moved into the services collection. It was on my list since we already knew it was terribad to be spinning up a new instance on every outbound activity and this addresses that.

new Claim(AuthenticationConstants.AppIdClaim, botAppId)
});

context.Services.Add<IIdentity>(claimsIdentity);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there really any value adding this to the services? You directly pass it to CreateConnectorClientAsync, so it's not like there's any code that's looking for it.

If you still think it should be registered, might I suggest you register it under an explicit, well known key (maybe something like "BotIdentity") rather than as "the" IIdentity since one could imagine there being some conflict around that interface at some point.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for extension SDKs to use. If you want to build a middleware for creating custom connector client (Teams extension SDK) or for creating other clients (e.g. Graph client or something).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will put it behind a key though.

string botAppId = GetBotId(claimsIdentity);
var context = new BotFrameworkTurnContext(botAppId, this, activity);
var context = new TurnContext(this, activity);
context.Services.Add<IIdentity>(claimsIdentity);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above. Registration of this seems unnecessary, but if you do it consider using the same explicit key approach mentioned above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

var context = new BotFrameworkTurnContext(botAppId, this, activity);
var context = new TurnContext(this, activity);
context.Services.Add<IIdentity>(claimsIdentity);
IConnectorClient connectorClient = await this.CreateConnectorClientAsync(claimsIdentity, activity.ServiceUrl);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

});

context.Services.Add<IIdentity>(claimsIdentity);
IConnectorClient connectorClient = await this.CreateConnectorClientAsync(claimsIdentity, reference.ServiceUrl);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

var context = new TurnContext(this, reference.GetPostToBotMessage());

// Hand craft Claims Identity.
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

Claim botAppIdClaim = (claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AudienceClaim)
// For requests from channel App Id is in Audience claim of JWT token. For emulator it is in AppId claim. For
// unauthenticated requests we have anonymouse identity provided auth is disabled.
Claim botAppIdClaim = (claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AudienceClaim)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

{
return botAppIdClaim.Value;
string botId = botAppIdClaim.Value;
MicrosoftAppCredentials appCredentials = await this.GetAppCredentialsAsync(botId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.


if (!_appCredentialMap.TryGetValue(appId, out var appCredentials))
{
string appPassword = await _credentialProvider.GetAppPasswordAsync(appId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent in our use of var vs explicit types. Right now the codebase follows a var-only approach so, religious debates aside, I think we should stick with that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildo.

@RamjotSingh

Copy link
Copy Markdown
Member Author

@drub0y I think I have addressed all the feedback. Let me know if you have any more concerns.

@drub0y drub0y left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove adding the IIdentity from the services since nothing uses it (more details inline), other than that I think this is good to go! If you have a reason to keep it, just lemme know, otherwise remove and I'm good to approve after that.


context.Services.Add<IIdentity>(claimsIdentity);
IConnectorClient connectorClient = await this.CreateConnectorClientAsync(claimsIdentity, reference.ServiceUrl);
context.Services.Add<IIdentity>("BotIdentity", claimsIdentity);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess I still question ever putting this into the services collection seeing as how you're already handing it directly to CreateConnectorClientAsync and using it directly there. No code ever goes back and looks for it in the Services collection. I would suggest we avoid putting extra "stuff" into the Services collection unless we're actually going to need to pull it out from there later and, as I said, this code doesn't ever do that... it only ever goes and pulls the IConnectorClient back out.

Given that, I would suggest removing this from the services collection until we actually deem it necessary.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIDentity is added so Extension SDKs like Teams can access the Bot AppId and then create their own ConnectorClients(or other clients). Plan is with access to BotAppId and ICredentialProvider they can build their own clients.

var context = new TurnContext(this, activity);
context.Services.Add<IIdentity>(claimsIdentity);
IConnectorClient connectorClient = await this.CreateConnectorClientAsync(claimsIdentity, activity.ServiceUrl);
context.Services.Add<IIdentity>("BotIdentity", claimsIdentity);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIDentity is added so Extension SDKs like Teams can access the Bot AppId and then create their own ConnectorClients(or other clients). Plan is with access to BotAppId and ICredentialProvider they can build their own clients.

@RamjotSingh
RamjotSingh merged commit 86377ee into master Mar 30, 2018
@cleemullins
cleemullins deleted the ramjsing/master-ConnectorClientInServices branch April 9, 2018 20:36
ShYuPe pushed a commit to ShYuPe/botbuilder-dotnet that referenced this pull request Aug 25, 2020
* Initial template for echo bot

* Added template zip file

* Added template zip file

* Readme for top level generators folder

* Pylint fixes for generator, readme updates

* Adding empty bot generator, ported latest on_error changes

* PR changes addressed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants