diff --git a/libraries/botframework-connector/botframework/connector/auth/__init__.py b/libraries/botframework-connector/botframework/connector/auth/__init__.py index 113112638..d58dcf5fa 100644 --- a/libraries/botframework-connector/botframework/connector/auth/__init__.py +++ b/libraries/botframework-connector/botframework/connector/auth/__init__.py @@ -17,6 +17,7 @@ from .microsoft_app_credentials import * from .microsoft_government_app_credentials import * from .certificate_app_credentials import * +from .certificate_government_app_credentials import * from .certificate_service_client_credential_factory import * from .claims_identity import * from .jwt_token_validation import * diff --git a/libraries/botframework-connector/botframework/connector/auth/certificate_government_app_credentials.py b/libraries/botframework-connector/botframework/connector/auth/certificate_government_app_credentials.py new file mode 100644 index 000000000..b2883cfa1 --- /dev/null +++ b/libraries/botframework-connector/botframework/connector/auth/certificate_government_app_credentials.py @@ -0,0 +1,51 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from .certificate_app_credentials import CertificateAppCredentials +from .government_constants import GovernmentConstants + + +class CertificateGovernmentAppCredentials(CertificateAppCredentials): + """ + GovernmentAppCredentials implementation using a certificate. + """ + + def __init__( + self, + app_id: str, + certificate_thumbprint: str, + certificate_private_key: str, + channel_auth_tenant: str = None, + oauth_scope: str = None, + certificate_public: str = None, + ): + """ + AppCredentials implementation using a certificate. + + :param app_id: + :param certificate_thumbprint: + :param certificate_private_key: + :param channel_auth_tenant: + :param oauth_scope: + :param certificate_public: public_certificate (optional) is public key certificate which will be sent + through ‘x5c’ JWT header only for subject name and issuer authentication to support cert auto rolls. + """ + + # super will set proper scope and endpoint. + super().__init__( + app_id=app_id, + channel_auth_tenant=channel_auth_tenant, + oauth_scope=oauth_scope, + certificate_thumbprint=certificate_thumbprint, + certificate_private_key=certificate_private_key, + certificate_public=certificate_public, + ) + + def _get_default_channelauth_tenant(self) -> str: + return GovernmentConstants.DEFAULT_CHANNEL_AUTH_TENANT + + def _get_to_channel_from_bot_loginurl_prefix(self) -> str: + return GovernmentConstants.TO_CHANNEL_FROM_BOT_LOGIN_URL_PREFIX + + def _get_to_channel_from_bot_oauthscope(self) -> str: + return GovernmentConstants.TO_CHANNEL_FROM_BOT_OAUTH_SCOPE diff --git a/libraries/botframework-connector/botframework/connector/auth/certificate_service_client_credential_factory.py b/libraries/botframework-connector/botframework/connector/auth/certificate_service_client_credential_factory.py index d930ea172..1e7205f33 100644 --- a/libraries/botframework-connector/botframework/connector/auth/certificate_service_client_credential_factory.py +++ b/libraries/botframework-connector/botframework/connector/auth/certificate_service_client_credential_factory.py @@ -5,7 +5,10 @@ from msrest.authentication import Authentication +from .authentication_constants import AuthenticationConstants +from .government_constants import GovernmentConstants from .certificate_app_credentials import CertificateAppCredentials +from .certificate_government_app_credentials import CertificateGovernmentAppCredentials from .microsoft_app_credentials import MicrosoftAppCredentials from .service_client_credentials_factory import ServiceClientCredentialsFactory @@ -58,13 +61,60 @@ async def create_credentials( if not await self.is_valid_app_id(app_id): raise Exception("Invalid app_id") - credentials = CertificateAppCredentials( - app_id, - self.certificate_thumbprint, - self.certificate_private_key, - self.tenant_id, - oauth_scope, - self.certificate_public, - ) + normalized_endpoint = login_endpoint.lower() if login_endpoint else "" + + if normalized_endpoint.startswith( + AuthenticationConstants.TO_CHANNEL_FROM_BOT_LOGIN_URL_PREFIX + ): + credentials = CertificateAppCredentials( + app_id, + self.certificate_thumbprint, + self.certificate_private_key, + self.tenant_id, + oauth_scope, + self.certificate_public, + ) + elif normalized_endpoint.startswith( + GovernmentConstants.TO_CHANNEL_FROM_BOT_LOGIN_URL_PREFIX + ): + credentials = CertificateGovernmentAppCredentials( + app_id, + self.certificate_thumbprint, + self.certificate_private_key, + self.tenant_id, + oauth_scope, + self.certificate_public, + ) + else: + credentials = _CertificatePrivateCloudAppCredentials( + app_id, + self.password, + self.tenant_id, + oauth_scope, + login_endpoint, + validate_authority, + ) return credentials + + +class _CertificatePrivateCloudAppCredentials(CertificateAppCredentials): + def __init__( + self, + app_id: str, + password: str, + tenant_id: str, + oauth_scope: str, + oauth_endpoint: str, + validate_authority: bool, + ): + super().__init__( + app_id, password, channel_auth_tenant=tenant_id, oauth_scope=oauth_scope + ) + + self.oauth_endpoint = oauth_endpoint + self._validate_authority = validate_authority + + @property + def validate_authority(self): + return self._validate_authority