From 96e27b573487b49f177a485d69a1fc8d88d034e4 Mon Sep 17 00:00:00 2001 From: Justin Wendlandt Date: Mon, 23 Jul 2018 11:16:14 -0700 Subject: [PATCH 1/5] Initial Commit. --- Standalone-Samples/Unity-Identity/.gitignore | 291 +++++++ .../Unity-Identity/Assembly-CSharp.csproj | 719 +++++++++++++++++ .../Unity-Identity/Assets/Plugins.meta | 8 + .../Unity-Identity/Assets/Scenes.meta | 8 + .../Assets/Scenes/SampleScene.unity | 368 +++++++++ .../Assets/Scenes/SampleScene.unity.meta | 7 + .../Unity-Identity/Assets/Scripts.meta | 8 + .../Unity-Identity/Assets/Scripts/MSAL.meta | 8 + .../Scripts/MSAL/AuthenticationResult.cs | 100 +++ .../Scripts/MSAL/AuthenticationResult.cs.meta | 11 + .../Scripts/MSAL/ClientApplicationBase.cs | 250 ++++++ .../MSAL/ClientApplicationBase.cs.meta | 11 + .../Assets/Scripts/MSAL/Features.meta | 8 + .../MSAL/Features/ConfidentialClient.meta | 8 + .../ClientAssertionCertificate.cs | 85 ++ .../ClientAssertionCertificate.cs.meta | 11 + .../ConfidentialClient/ClientCredential.cs | 69 ++ .../ClientCredential.cs.meta | 11 + .../ConfidentialClientApplication.cs | 246 ++++++ .../ConfidentialClientApplication.cs.meta | 11 + .../IConfidentialClientApplication.cs | 118 +++ .../IConfidentialClientApplication.cs.meta | 11 + .../ConfidentialClient/JsonWebToken.cs | 225 ++++++ .../ConfidentialClient/JsonWebToken.cs.meta | 11 + .../Scripts/MSAL/Features/EventSource.meta | 8 + .../Features/EventSource/MsalEventSource.cs | 59 ++ .../EventSource/MsalEventSource.cs.meta | 11 + .../Features/EventSource/PlatformLogger.cs | 67 ++ .../EventSource/PlatformLogger.cs.meta | 11 + .../Scripts/MSAL/Features/PublicClient.meta | 8 + .../PublicClient/PublicClientApplication.cs | 47 ++ .../PublicClientApplication.cs.meta | 11 + .../Scripts/MSAL/Features/TokenCache.meta | 8 + .../Features/TokenCache/TokenCacheAccessor.cs | 115 +++ .../TokenCache/TokenCacheAccessor.cs.meta | 11 + .../TokenCache/TokenCacheExtensions.cs | 125 +++ .../TokenCache/TokenCacheExtensions.cs.meta | 11 + .../Scripts/MSAL/IClientApplicationBase.cs | 115 +++ .../MSAL/IClientApplicationBase.cs.meta | 11 + .../Scripts/MSAL/IPublicClientApplication.cs | 240 ++++++ .../MSAL/IPublicClientApplication.cs.meta | 11 + .../Assets/Scripts/MSAL/IUser.cs | 57 ++ .../Assets/Scripts/MSAL/IUser.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal.meta | 8 + .../MSAL/Internal/AuthorizationResult.cs | 124 +++ .../MSAL/Internal/AuthorizationResult.cs.meta | 11 + .../Scripts/MSAL/Internal/Base64UrlHelpers.cs | 108 +++ .../MSAL/Internal/Base64UrlHelpers.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/Cache.meta | 8 + .../Internal/Cache/AccessTokenCacheItem.cs | 140 ++++ .../Cache/AccessTokenCacheItem.cs.meta | 11 + .../Internal/Cache/AccessTokenCacheKey.cs | 88 ++ .../Cache/AccessTokenCacheKey.cs.meta | 11 + .../MSAL/Internal/Cache/BaseTokenCacheItem.cs | 72 ++ .../Internal/Cache/BaseTokenCacheItem.cs.meta | 11 + .../Internal/Cache/ITokenCacheAccessor.cs | 54 ++ .../Cache/ITokenCacheAccessor.cs.meta | 11 + .../Internal/Cache/RefreshTokenCacheItem.cs | 95 +++ .../Cache/RefreshTokenCacheItem.cs.meta | 11 + .../Internal/Cache/RefreshTokenCacheKey.cs | 57 ++ .../Cache/RefreshTokenCacheKey.cs.meta | 11 + .../MSAL/Internal/Cache/TokenCacheKeyBase.cs | 51 ++ .../Internal/Cache/TokenCacheKeyBase.cs.meta | 11 + .../Scripts/MSAL/Internal/ClientInfo.cs | 86 ++ .../Scripts/MSAL/Internal/ClientInfo.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/Constants.cs | 202 +++++ .../Scripts/MSAL/Internal/Constants.cs.meta | 11 + .../Scripts/MSAL/Internal/Extensions.cs | 73 ++ .../Scripts/MSAL/Internal/Extensions.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/Http.meta | 8 + .../MSAL/Internal/Http/HttpClientFactory.cs | 76 ++ .../Internal/Http/HttpClientFactory.cs.meta | 11 + .../Http/HttpMessageHandlerFactory.cs | 55 ++ .../Http/HttpMessageHandlerFactory.cs.meta | 11 + .../Scripts/MSAL/Internal/Http/HttpRequest.cs | 180 +++++ .../MSAL/Internal/Http/HttpRequest.cs.meta | 11 + .../MSAL/Internal/Http/HttpResponse.cs | 43 + .../MSAL/Internal/Http/HttpResponse.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/ILogger.cs | 44 + .../Scripts/MSAL/Internal/ILogger.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/IdToken.cs | 112 +++ .../Scripts/MSAL/Internal/IdToken.cs.meta | 11 + .../Scripts/MSAL/Internal/Instance.meta | 8 + .../MSAL/Internal/Instance/AadAuthority.cs | 114 +++ .../Internal/Instance/AadAuthority.cs.meta | 11 + .../MSAL/Internal/Instance/AdfsAuthority.cs | 162 ++++ .../Internal/Instance/AdfsAuthority.cs.meta | 11 + .../Instance/AdfsWebFingerResponse.cs | 61 ++ .../Instance/AdfsWebFingerResponse.cs.meta | 11 + .../MSAL/Internal/Instance/Authority.cs | 259 ++++++ .../MSAL/Internal/Instance/Authority.cs.meta | 11 + .../MSAL/Internal/Instance/B2CAuthority.cs | 63 ++ .../Internal/Instance/B2CAuthority.cs.meta | 11 + .../Internal/Instance/DrsMetadataResponse.cs | 53 ++ .../Instance/DrsMetadataResponse.cs.meta | 11 + .../Instance/InstanceDiscoveryResponse.cs | 39 + .../InstanceDiscoveryResponse.cs.meta | 11 + .../Instance/TenantDiscoveryResponse.cs | 52 ++ .../Instance/TenantDiscoveryResponse.cs.meta | 11 + .../Scripts/MSAL/Internal/Interfaces.meta | 8 + .../MSAL/Internal/Interfaces/IWebUI.cs | 41 + .../MSAL/Internal/Interfaces/IWebUI.cs.meta | 11 + .../MSAL/Internal/Interfaces/IWebUIFactory.cs | 34 + .../Internal/Interfaces/IWebUIFactory.cs.meta | 11 + .../Scripts/MSAL/Internal/JsonHelper.cs | 73 ++ .../Scripts/MSAL/Internal/JsonHelper.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/MsalError.cs | 86 ++ .../Scripts/MSAL/Internal/MsalError.cs.meta | 11 + .../Scripts/MSAL/Internal/MsalHelpers.cs | 378 +++++++++ .../Scripts/MSAL/Internal/MsalHelpers.cs.meta | 11 + .../Scripts/MSAL/Internal/MsalIdHelper.cs | 125 +++ .../MSAL/Internal/MsalIdHelper.cs.meta | 11 + .../Assets/Scripts/MSAL/Internal/OAuth2.meta | 8 + .../MSAL/Internal/OAuth2/OAuth2Client.cs | 198 +++++ .../MSAL/Internal/OAuth2/OAuth2Client.cs.meta | 11 + .../Internal/OAuth2/OAuth2ResponseBase.cs | 59 ++ .../OAuth2/OAuth2ResponseBase.cs.meta | 11 + .../MSAL/Internal/OAuth2/OAuthConstants.cs | 114 +++ .../Internal/OAuth2/OAuthConstants.cs.meta | 11 + .../MSAL/Internal/OAuth2/TokenResponse.cs | 74 ++ .../Internal/OAuth2/TokenResponse.cs.meta | 11 + .../MSAL/Internal/PlatformInformationBase.cs | 85 ++ .../Internal/PlatformInformationBase.cs.meta | 11 + .../Scripts/MSAL/Internal/PlatformPlugin.cs | 98 +++ .../MSAL/Internal/PlatformPlugin.cs.meta | 11 + .../Scripts/MSAL/Internal/RequestContext.cs | 46 ++ .../MSAL/Internal/RequestContext.cs.meta | 11 + .../Scripts/MSAL/Internal/Requests.meta | 8 + .../AuthenticationRequestParameters.cs | 165 ++++ .../AuthenticationRequestParameters.cs.meta | 11 + .../Requests/AuthorizationCodeRequest.cs | 61 ++ .../Requests/AuthorizationCodeRequest.cs.meta | 11 + .../Requests/ClientCredentialRequest.cs | 72 ++ .../Requests/ClientCredentialRequest.cs.meta | 11 + .../Internal/Requests/InteractiveRequest.cs | 274 +++++++ .../Requests/InteractiveRequest.cs.meta | 11 + .../Internal/Requests/OnBehalfOfRequest.cs | 77 ++ .../Requests/OnBehalfOfRequest.cs.meta | 11 + .../MSAL/Internal/Requests/RequestBase.cs | 315 ++++++++ .../Internal/Requests/RequestBase.cs.meta | 11 + .../MSAL/Internal/Requests/SilentRequest.cs | 108 +++ .../Internal/Requests/SilentRequest.cs.meta | 11 + .../Scripts/MSAL/Internal/Telemetry.meta | 8 + .../MSAL/Internal/Telemetry/ApiEvent.cs | 173 ++++ .../MSAL/Internal/Telemetry/ApiEvent.cs.meta | 11 + .../MSAL/Internal/Telemetry/CacheEvent.cs | 67 ++ .../Internal/Telemetry/CacheEvent.cs.meta | 11 + .../MSAL/Internal/Telemetry/DefaultEvent.cs | 45 ++ .../Internal/Telemetry/DefaultEvent.cs.meta | 11 + .../Scripts/MSAL/Internal/Telemetry/Event.cs | 90 +++ .../MSAL/Internal/Telemetry/Event.cs.meta | 11 + .../MSAL/Internal/Telemetry/HttpEvent.cs | 93 +++ .../MSAL/Internal/Telemetry/HttpEvent.cs.meta | 11 + .../Telemetry/TelemetryTokenCacheAccessor.cs | 92 +++ .../TelemetryTokenCacheAccessor.cs.meta | 11 + .../MSAL/Internal/Telemetry/UiEvent.cs | 45 ++ .../MSAL/Internal/Telemetry/UiEvent.cs.meta | 11 + .../Assets/Scripts/MSAL/Logger.cs | 267 +++++++ .../Assets/Scripts/MSAL/Logger.cs.meta | 11 + .../Scripts/MSAL/MsalClientException.cs | 151 ++++ .../Scripts/MSAL/MsalClientException.cs.meta | 11 + .../Assets/Scripts/MSAL/MsalException.cs | 117 +++ .../Assets/Scripts/MSAL/MsalException.cs.meta | 11 + .../Scripts/MSAL/MsalServiceException.cs | 178 +++++ .../Scripts/MSAL/MsalServiceException.cs.meta | 11 + .../Scripts/MSAL/MsalUiRequiredException.cs | 97 +++ .../MSAL/MsalUiRequiredException.cs.meta | 11 + .../Assets/Scripts/MSAL/Platforms.meta | 8 + .../Assets/Scripts/MSAL/Platforms/Unity.meta | 8 + .../Platforms/Unity/CryptographyHelper.cs | 70 ++ .../Unity/CryptographyHelper.cs.meta | 11 + .../Platforms/Unity/PlatformInformation.cs | 65 ++ .../Unity/PlatformInformation.cs.meta | 11 + .../MSAL/Platforms/Unity/WebUIFactory.cs | 41 + .../MSAL/Platforms/Unity/WebUIFactory.cs.meta | 11 + .../Scripts/MSAL/PublicClientApplication.cs | 380 +++++++++ .../MSAL/PublicClientApplication.cs.meta | 11 + .../Assets/Scripts/MSAL/Telemetry.cs | 209 +++++ .../Assets/Scripts/MSAL/Telemetry.cs.meta | 11 + .../Assets/Scripts/MSAL/TokenCache.cs | 752 ++++++++++++++++++ .../Assets/Scripts/MSAL/TokenCache.cs.meta | 11 + .../MSAL/TokenCacheNotificationArgs.cs | 50 ++ .../MSAL/TokenCacheNotificationArgs.cs.meta | 11 + .../Assets/Scripts/MSAL/UIBehavior.cs | 111 +++ .../Assets/Scripts/MSAL/UIBehavior.cs.meta | 11 + .../Assets/Scripts/MSAL/UIParent.cs | 88 ++ .../Assets/Scripts/MSAL/UIParent.cs.meta | 11 + .../Assets/Scripts/MSAL/User.cs | 79 ++ .../Assets/Scripts/MSAL/User.cs.meta | 11 + .../Assets/Scripts/MSAL/UserAssertion.cs | 84 ++ .../Assets/Scripts/MSAL/UserAssertion.cs.meta | 11 + .../Assets/Scripts/StartupScript.cs | 26 + .../Assets/Scripts/StartupScript.cs.meta | 11 + .../ProjectSettings/AudioManager.asset | 17 + .../ProjectSettings/ClusterInputManager.asset | 6 + .../ProjectSettings/DynamicsManager.asset | 29 + .../ProjectSettings/EditorBuildSettings.asset | 11 + .../ProjectSettings/EditorSettings.asset | 21 + .../ProjectSettings/GraphicsSettings.asset | 61 ++ .../ProjectSettings/InputManager.asset | 295 +++++++ .../ProjectSettings/NavMeshAreas.asset | 91 +++ .../ProjectSettings/NetworkManager.asset | 8 + .../ProjectSettings/Physics2DSettings.asset | 37 + .../ProjectSettings/PresetManager.asset | 27 + .../ProjectSettings/ProjectSettings.asset | 671 ++++++++++++++++ .../ProjectSettings/ProjectVersion.txt | 1 + .../ProjectSettings/QualitySettings.asset | 190 +++++ .../ProjectSettings/TagManager.asset | 43 + .../ProjectSettings/TimeManager.asset | 9 + .../UnityConnectSettings.asset | 34 + .../Unity-Identity/TestingMsal.sln | 20 + 211 files changed, 14277 insertions(+) create mode 100644 Standalone-Samples/Unity-Identity/.gitignore create mode 100644 Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj create mode 100644 Standalone-Samples/Unity-Identity/Assets/Plugins.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scenes.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/AudioManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/ClusterInputManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/DynamicsManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/EditorBuildSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/EditorSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/GraphicsSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/InputManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/NavMeshAreas.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/NetworkManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/Physics2DSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/PresetManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/ProjectSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/ProjectVersion.txt create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/QualitySettings.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/TagManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/TimeManager.asset create mode 100644 Standalone-Samples/Unity-Identity/ProjectSettings/UnityConnectSettings.asset create mode 100644 Standalone-Samples/Unity-Identity/TestingMsal.sln diff --git a/Standalone-Samples/Unity-Identity/.gitignore b/Standalone-Samples/Unity-Identity/.gitignore new file mode 100644 index 0000000..0224a43 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/.gitignore @@ -0,0 +1,291 @@ +# Unity3D Autogenerated VS/MD solution and project files +/**/Unity/**/UWP +/**/Unity/**/Unprocessed +/**/Unity/Tools/ + +# Unity3D Player Binaries +Unity*.dll +WinRTLegacy.dll + +# Unity3D C# Project Binaries +Assembly-CSharp*.dll + +# Unity3D Autogenerated Player files +Players/ + +# Unity3D Exported Data files +Data/ + +# UWP Exported Binaries +/**/UWP/**/*.dll +/**/UWP/**/*.exe + +# HoloLens Binaries +SharingClient.dll +PlaneFinding.dll + +# Unity3D Generated File On Crash Reports +sysinfo.txt +Lib/*.suo + +# NuGet Files +project.lock.json + +# Built application files +/*/build/ + +# Crashlytics configuations +com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +local.properties + +# Gradle generated files +.gradle/ + +# Signing files +.signing/ + +# User-specific configurations +.idea/libraries/ +.idea/workspace.xml +.idea/tasks.xml +.idea/.name +.idea/compiler.xml +.idea/copyright/profiles_settings.xml +.idea/encodings.xml +.idea/misc.xml +.idea/modules.xml +.idea/scopes/scope_settings.xml +.idea/vcs.xml +*.iml + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + + + + + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Rr]ef/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Packaging libraries +[Pp]ackaging/Builds/* +[Pp]ackaging/Packages/* + +# Packaging content OK +![Pp]ackaging/Content/** + +# Always get Unity root tools +![U]nity/** + +# Always ignore Unity Library and Temp folders +**/[Ll]ibrary/* +**/[Tt]emp/ + +# Visual Studo 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# VSIX Packages OK +!**/VisualStudio/VSFeatureEngine/Packages/* +# Lock files +**/project.lock.json + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.[Cc]ache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +# *.pfx // Allowing PFX because all PFX files are for samples +*.publishsettings +node_modules/ +bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt +mixedreality-azure-samples.sln +mixedreality-azure-samples.csproj +mixedreality-azure-samples.Player.csproj \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj new file mode 100644 index 0000000..e010e9e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj @@ -0,0 +1,719 @@ + + + + 6 + + + Debug + AnyCPU + 10.0.20506 + 2.0 + + {0037223C-A948-414E-4BF6-F39E8B8A73BD} + Library + Properties + Assembly-CSharp + v4.7.1 + 512 + . + + + true + full + false + Temp\bin\Debug\ + DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_2_0;UNITY_2018_2;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;UNITY_ANALYTICS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_TEXTURE_STREAMING;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE;UNITY_POST_PROCESSING_STACK_V2;ENABLE_MONO + prompt + 4 + 0169 + False + + + pdbonly + true + Temp\bin\Release\ + prompt + 4 + 0169 + False + + + true + true + false + false + false + + + {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Unity/VSTU + Game:1 + StandaloneWindows64:19 + 2018.2.0x-ImprovedPrefabs + + + + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll + + + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEditor.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll + + + C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll + + + C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll + + + C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.TextMeshPro.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/Unity.Locator.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/ref/2.0.0/netstandard.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/Microsoft.Win32.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.AppContext.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Concurrent.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.NonGeneric.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Specialized.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.EventBasedAsync.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.TypeConverter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Console.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Data.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Contracts.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Debug.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.FileVersionInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Process.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.StackTrace.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TextWriterTraceListener.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tools.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TraceSource.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tracing.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Drawing.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Dynamic.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Calendars.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.ZipFile.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.DriveInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Watcher.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.IsolatedStorage.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.MemoryMappedFiles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Pipes.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.UnmanagedMemoryStream.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Expressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Queryable.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Http.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NameResolution.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NetworkInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Ping.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Requests.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Sockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebHeaderCollection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.Client.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ObjectModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Reader.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.ResourceManager.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Writer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.CompilerServices.VisualC.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Handles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.RuntimeInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Formatters.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Json.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Claims.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Algorithms.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Csp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.X509Certificates.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Principal.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.SecureString.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.RegularExpressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Overlapped.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Thread.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.ThreadPool.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Timer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ValueTuple.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.ReaderWriter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlSerializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/Extensions/2.0.0/System.Numerics.Vectors.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/Extensions/2.0.0/System.Runtime.InteropServices.WindowsRuntime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/mscorlib.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ComponentModel.Composition.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Core.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Data.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Drawing.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.IO.Compression.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Net.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Runtime.Serialization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ServiceModel.Web.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Transactions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Web.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Windows.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Serialization.dll + + + + + + \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Plugins.meta b/Standalone-Samples/Unity-Identity/Assets/Plugins.meta new file mode 100644 index 0000000..7375000 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d84109a9d5e886242bb5a6adf175c42f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scenes.meta b/Standalone-Samples/Unity-Identity/Assets/Scenes.meta new file mode 100644 index 0000000..17072cf --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f704ae4b4f98ae41a0bce26658850c1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity b/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity new file mode 100644 index 0000000..fee917d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity @@ -0,0 +1,368 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &170076733 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 170076735} + - component: {fileID: 170076734} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &170076735 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 170076733} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!108 &170076734 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 170076733} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 1 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!1 &282840810 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 282840814} + - component: {fileID: 282840813} + - component: {fileID: 282840811} + - component: {fileID: 282840812} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &282840814 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 282840810} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &282840813 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 282840810} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 1 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!81 &282840811 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 282840810} + m_Enabled: 1 +--- !u!114 &282840812 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 282840810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e3ed56f1e009a384f9cc7d196b9e8043, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1770111396 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1770111400} + - component: {fileID: 1770111399} + - component: {fileID: 1770111398} + - component: {fileID: 1770111397} + m_Layer: 0 + m_Name: Sphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1770111400 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770111396} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.566, z: -7.07} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &1770111399 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770111396} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1770111398 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770111396} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RenderingLayerMask: 4294967295 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!135 &1770111397 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770111396} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 10 + m_AtlasSize: 512 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 256 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity.meta b/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity.meta new file mode 100644 index 0000000..9531828 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 99c9720ab356a0642a771bea13969a05 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts.meta new file mode 100644 index 0000000..e08ac37 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5198ea942d9338d41bf7286d6d26fbcf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL.meta new file mode 100644 index 0000000..100dcaa --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fce0b9f265a294e4495cc8e4e4053ce6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs new file mode 100644 index 0000000..20e2f84 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs @@ -0,0 +1,100 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Cache; +using System; +using System.Collections.Generic; + +namespace Microsoft.Identity.Client +{ + /// + /// Contains the results of one token acquisition operation. + /// + public class AuthenticationResult + { + private const string Oauth2AuthorizationHeader = "Bearer "; + private readonly AccessTokenCacheItem _accessTokenCacheItem; + + internal AuthenticationResult() + { + } + + internal AuthenticationResult(AccessTokenCacheItem accessTokenCacheItem) + { + _accessTokenCacheItem = accessTokenCacheItem; + } + + /// + /// Gets the Access Token requested. + /// + public virtual string AccessToken => _accessTokenCacheItem.AccessToken; + + /// + /// Gets the Unique Id of the user. + /// + public virtual string UniqueId => _accessTokenCacheItem.IdToken?.GetUniqueId(); + + /// + /// Gets the point in time in which the Access Token returned in the Token property ceases to be valid. + /// This value is calculated based on current UTC time measured locally and the value expiresIn received from the + /// service. + /// + public virtual DateTimeOffset ExpiresOn => _accessTokenCacheItem.ExpiresOn; + + /// + /// Gets an identifier for the tenant the token was acquired from. This property will be null if tenant information is + /// not returned by the service. + /// + public virtual string TenantId => _accessTokenCacheItem.IdToken?.TenantId; + + /// + /// Gets the user object. Some elements in User might be null if not returned by the + /// service. It can be passed back in some API overloads to identify which user should be used. + /// + public virtual IUser User => _accessTokenCacheItem.User; + + /// + /// Gets the entire Id Token if returned by the service or null if no Id Token is returned. + /// + public virtual string IdToken => _accessTokenCacheItem.RawIdToken; + + /// + /// Gets the scope values returned from the service. + /// + public virtual IEnumerable Scopes => _accessTokenCacheItem.ScopeSet.AsArray(); + + /// + /// Creates authorization header from authentication result. + /// + /// Created authorization header + public virtual string CreateAuthorizationHeader() + { + return Oauth2AuthorizationHeader + AccessToken; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs.meta new file mode 100644 index 0000000..bc8395a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/AuthenticationResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8cfc31bfc28cbb4fbbd884c138a15a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs new file mode 100644 index 0000000..6236fba --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs @@ -0,0 +1,250 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.Requests; +using Microsoft.Identity.Client.Internal.Telemetry; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client +{ + /// + /// Abstract class containing common API methods and properties. Both PublicClientApplication and ConfidentialClientApplication extend this class. + /// + public abstract class ClientApplicationBase + { + private TokenCache _userTokenCache; + + /// + /// Default Authority used for interactive calls. + /// + protected const string DefaultAuthority = "https://login.microsoftonline.com/common/"; + + /// + /// + /// + /// + /// + /// + /// + protected ClientApplicationBase(string clientId, string authority, string redirectUri, + bool validateAuthority) + { + ClientId = clientId; + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, validateAuthority); + Authority = authorityInstance.CanonicalAuthority; + RedirectUri = redirectUri; + ValidateAuthority = validateAuthority; + if (UserTokenCache != null) + { + UserTokenCache.ClientId = clientId; + } + + RequestContext requestContext = new RequestContext(Guid.Empty, null); + + //var msg = string.Format(CultureInfo.InvariantCulture, + // "MSAL {0} with assembly version '{1}', file version '{2}' and informational version '{3}' is running...", + // PlatformPlugin.PlatformInformation.GetProductName(), MsalIdHelper.GetMsalVersion(), + // MsalIdHelper.GetAssemblyFileVersion(), MsalIdHelper.GetAssemblyInformationalVersion()); + //requestContext.Logger.Info(msg); + //requestContext.Logger.InfoPii(msg); + } + + /// + /// Identifier of the component consuming MSAL and it is intended for libraries/SDKs that consume MSAL. This will allow for disambiguation between MSAL usage by the app vs MSAL usage by component libraries. + /// + public string Component { get; set; } + + /// + /// Authority provided by the developer or default authority used by the library. + /// + public string Authority { get; } + + /// + /// Will be a default value. Can be overridden by the developer. Once set, application will bind to the client Id. + /// + public string ClientId { get; } + + /// + /// Redirect Uri configured in the app registration portal. PublicClientApplication has a default value of + /// urn:ietf:wg:oauth:2.0:oob.This default does not apply to iOS and Android as the library needs to leverage + /// system webview for authentication. + /// + public string RedirectUri { get; set; } + + /// + /// Sets or Gets the custom query parameters that may be sent to the STS for dogfood testing. This parameter should not be set by the + /// developers as it may have adverse effect on the application. + /// + public string SliceParameters { get; set; } + + /// + /// Token Cache instance for storing User tokens. + /// + internal TokenCache UserTokenCache + { + get { return _userTokenCache; } + set + { + _userTokenCache = value; + if (_userTokenCache != null) + { + _userTokenCache.ClientId = ClientId; + } + } + } + + /// + /// Gets/sets a value indicating whether authority validation is ON or OFF. Value is true by default. + /// It should be set to false by the deveopers for B2C applications. + /// + public bool ValidateAuthority { get; set; } + + /// + /// Returns a User centric view over the cache that provides a list of all the available users in the cache for the application. + /// + public IEnumerable Users + { + get + { + RequestContext requestContext = new RequestContext(Guid.Empty, null); + if (UserTokenCache == null) + { + const string msg = "Token cache is null or empty. Returning empty list of users."; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + return Enumerable.Empty(); + } + + return UserTokenCache.GetUsers(new Uri(Authority).Host, requestContext); + } + } + + /// + /// Get user by identifier from users available in the cache. + /// + /// user identifier + public IUser GetUser(string identifier) + { + return Users.FirstOrDefault(user => user.Identifier.Equals(identifier)); + } + + /// + /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. + /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or + /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. + /// + /// Array of scopes requested for resource + /// User for which the token is requested. + /// + public async Task AcquireTokenSilentAsync(IEnumerable scopes, IUser user) + { + return + await + AcquireTokenSilentCommonAsync(null, scopes, user, false, ApiEvent.ApiIds.AcquireTokenSilentWithoutAuthority) + .ConfigureAwait(false); + } + + /// + /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. + /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or + /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. + /// + /// Array of scopes requested for resource + /// User for which the token is requested + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using the refresh token if available + /// + public async Task AcquireTokenSilentAsync(IEnumerable scopes, IUser user, + string authority, bool forceRefresh) + { + Authority authorityInstance = null; + if (!string.IsNullOrEmpty(authority)) + { + authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + } + + return + await + AcquireTokenSilentCommonAsync(authorityInstance, scopes, user, + forceRefresh, ApiEvent.ApiIds.AcquireTokenSilentWithAuthority).ConfigureAwait(false); + } + + /// + /// Removes all cached tokens for the specified user. + /// + /// instance of the user that needs to be removed + public void Remove(IUser user) + { + RequestContext requestContext = CreateRequestContext(Guid.Empty); + if (user == null || UserTokenCache == null) + { + return; + } + + UserTokenCache.Remove(user, requestContext); + } + + internal async Task AcquireTokenSilentCommonAsync(Authority authority, + IEnumerable scopes, IUser user, bool forceRefresh, ApiEvent.ApiIds apiId) + { + var handler = new SilentRequest( + CreateRequestParameters(authority, scopes, user, UserTokenCache), + forceRefresh) + { ApiId = apiId }; + return await handler.RunAsync().ConfigureAwait(false); + } + + internal virtual AuthenticationRequestParameters CreateRequestParameters(Authority authority, + IEnumerable scopes, + IUser user, TokenCache cache) + { + return new AuthenticationRequestParameters + { + SliceParameters = SliceParameters, + Authority = authority, + ClientId = ClientId, + TokenCache = cache, + User = user, + Scope = scopes.CreateSetFromEnumerable(), + RedirectUri = new Uri(RedirectUri), + RequestContext = CreateRequestContext(Guid.Empty), + ValidateAuthority = ValidateAuthority + }; + } + + internal RequestContext CreateRequestContext(Guid correlationId) + { + correlationId = (correlationId != Guid.Empty) ? correlationId : Guid.NewGuid(); + return new RequestContext(correlationId, Component); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta new file mode 100644 index 0000000..20d7237 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6664b1207e06edf41ae7e1ffa63c334c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta new file mode 100644 index 0000000..2ac5535 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9056496dc597f4849842fa16abab6463 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta new file mode 100644 index 0000000..70ea9ec --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 70e24b9bcc9390a4ba7f08d20eb062a1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs new file mode 100644 index 0000000..7f5ff10 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs @@ -0,0 +1,85 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; +using System; +using System.Security.Cryptography.X509Certificates; + +namespace Microsoft.Identity.Client +{ + /// + /// Containing certificate used to create client assertion. + /// + public sealed class ClientAssertionCertificate + { + /// + /// Constructor to create credential using certificate. + /// + /// The certificate used as credential. + public ClientAssertionCertificate(X509Certificate2 certificate) + { + if (certificate == null) throw new ArgumentNullException(nameof(certificate)); + + Certificate = certificate; + +#if DESKTOP + if (certificate.PublicKey. Key.KeySize < MinKeySizeInBits) + { + throw new ArgumentOutOfRangeException(nameof(certificate), + string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.CertificateKeySizeTooSmallTemplate, + MinKeySizeInBits)); + } +#endif + + } + + /// + /// Gets minimum X509 certificate key size in bits + /// + public static int MinKeySizeInBits + { + get { return 2048; } + } + + /// + /// Gets the certificate used as credential. + /// + public X509Certificate2 Certificate { get; } + + internal byte[] Sign(string message) + { + CryptographyHelper helper = new CryptographyHelper(); + return helper.SignWithCertificate(message, Certificate); + } + + internal string Thumbprint + { + // Thumbprint should be url encoded + get { return Base64UrlHelpers.Encode(Certificate.GetCertHash()); } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta new file mode 100644 index 0000000..24cf2c2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c9f6f3f7b8883242a53a4ceb687510b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs new file mode 100644 index 0000000..f8656e2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client +{ + /// + /// Meant to be used in confidential client applications. Allows developers to + /// pass either client secret or client assertion certificate of their application. + /// + public sealed class ClientCredential + { +#if !FACADE + /// + /// Constructor provide client assertion certificate + /// + /// certificate of the client requesting the token. + public ClientCredential(ClientAssertionCertificate certificate) + { + Certificate = certificate; + } + + internal ClientAssertionCertificate Certificate { get; private set; } + internal string Assertion { get; set; } + internal long ValidTo { get; set; } +#endif + + /// + /// Constructor to provide client secret + /// + /// Secret of the client requesting the token. + public ClientCredential(string secret) + { + if (string.IsNullOrWhiteSpace(secret)) + { + throw new ArgumentNullException(nameof(secret)); + } + + Secret = secret; + } + + internal string Secret { get; private set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta new file mode 100644 index 0000000..688b757 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90934d28eaf1f5d49b852704f94a85a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs new file mode 100644 index 0000000..0e94609 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs @@ -0,0 +1,246 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.Requests; +using Microsoft.Identity.Client.Internal.Telemetry; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client +{ + /// + /// Class to be used for confidential client applications like Web Apps/API. + /// + public sealed class ConfidentialClientApplication : ClientApplicationBase, IConfidentialClientApplication + { + /// + /// Constructor to create instance of the class + /// + /// Client Id of the application. REQUIRED. + /// Redirect URI of the application. REQUIRED. + /// Client credential for the application. Could be a certificate or a secret. REQUIRED. + /// Token cache for saving user tokens. OPTIONAL. + /// Token cache for saving application/client tokens. OPTIONAL. + public ConfidentialClientApplication(string clientId, string redirectUri, + ClientCredential clientCredential, TokenCache userTokenCache, TokenCache appTokenCache) + : this(clientId, DefaultAuthority, redirectUri, clientCredential, userTokenCache, appTokenCache) + { + } + + /// + /// Constructor to create instance of the class + /// + /// Client Id of the application. REQUIRED. + /// Authority to be used for the client application. REQUIRED. + /// Redirect URI of the application. REQUIRED. + /// Client credential for the application. Could be a certificate or a secret. REQUIRED. + /// Token cache for saving user tokens. OPTIONAL. + /// Token cache for saving application/client tokens. OPTIONAL. + public ConfidentialClientApplication(string clientId, string authority, string redirectUri, + ClientCredential clientCredential, TokenCache userTokenCache, TokenCache appTokenCache) + : base(clientId, authority, redirectUri, true) + { + ClientCredential = clientCredential; + UserTokenCache = userTokenCache; + if (UserTokenCache != null) + { + UserTokenCache.ClientId = clientId; + } + + AppTokenCache = appTokenCache; + if (AppTokenCache != null) + { + AppTokenCache.ClientId = clientId; + } + } + + /// + /// Acquires token using On-Behalf-Of flow. + /// + /// Array of scopes requested for resource + /// Instance of UserAssertion containing user's token. + /// Authentication result containing token of the user for the requested scopes + public async Task AcquireTokenOnBehalfOfAsync(IEnumerable scopes, UserAssertion userAssertion) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenOnBehalfCommonAsync(authority, scopes, userAssertion, ApiEvent.ApiIds.AcquireTokenOnBehalfOfWithScopeUser) + .ConfigureAwait(false); + } + + /// + /// Acquires token using On-Behalf-Of flow. + /// + /// Array of scopes requested for resource + /// Instance of UserAssertion containing user's token. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user for the requested scopes + public async Task AcquireTokenOnBehalfOfAsync(IEnumerable scopes, UserAssertion userAssertion, + string authority) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + return + await + AcquireTokenOnBehalfCommonAsync(authorityInstance, scopes, userAssertion, ApiEvent.ApiIds.AcquireTokenOnBehalfOfWithScopeUserAuthority) + .ConfigureAwait(false); + } + + /// + /// Acquires security token from the authority using authorization code previously received. + /// This method does not lookup token cache, but stores the result in it, so it can be looked up using other methods such as . + /// + /// The authorization code received from service authorization endpoint. + /// Array of scopes requested for resource + /// Authentication result containing token of the user for the requested scopes + public async Task AcquireTokenByAuthorizationCodeAsync(string authorizationCode, IEnumerable scopes) + { + return + await + AcquireTokenByAuthorizationCodeCommonAsync( + authorizationCode, scopes, new Uri(RedirectUri), + ApiEvent.ApiIds.AcquireTokenByAuthorizationCodeWithCodeScope).ConfigureAwait(false); + } + + /// + /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. + /// + /// Array of scopes requested for resource + /// Authentication result containing application token for the requested scopes + public async Task AcquireTokenForClientAsync(IEnumerable scopes) + { + return + await + AcquireTokenForClientCommonAsync(scopes, false, ApiEvent.ApiIds.AcquireTokenForClientWithScope).ConfigureAwait(false); + } + + /// + /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. + /// + /// Array of scopes requested for resource + /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using client credentials + /// Authentication result containing application token for the requested scopes + public async Task AcquireTokenForClientAsync(IEnumerable scopes, bool forceRefresh) + { + return + await + AcquireTokenForClientCommonAsync(scopes, forceRefresh, ApiEvent.ApiIds.AcquireTokenForClientWithScopeRefresh).ConfigureAwait(false); + } + + /// + /// Gets URL of the authorize endpoint including the query parameters. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// URL of the authorize endpoint including the query parameters. + public async Task GetAuthorizationRequestUrlAsync(IEnumerable scopes, string loginHint, + string extraQueryParameters) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + var requestParameters = + CreateRequestParameters(authority, scopes, null, UserTokenCache); + requestParameters.ClientId = ClientId; + requestParameters.ExtraQueryParameters = extraQueryParameters; + + var handler = + new InteractiveRequest(requestParameters, null, loginHint, UIBehavior.SelectAccount, null); + return await handler.CreateAuthorizationUriAsync().ConfigureAwait(false); + } + + /// + /// Gets URL of the authorize endpoint including the query parameters. + /// + /// Array of scopes requested for resource + /// Address to return to upon receiving a response from the authority. + /// Identifier of the user. Generally a UPN. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// URL of the authorize endpoint including the query parameters. + public async Task GetAuthorizationRequestUrlAsync(IEnumerable scopes, string redirectUri, string loginHint, + string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + var requestParameters = CreateRequestParameters(authorityInstance, scopes, null, + UserTokenCache); + requestParameters.RedirectUri = new Uri(redirectUri); + requestParameters.ClientId = ClientId; + requestParameters.ExtraQueryParameters = extraQueryParameters; + + var handler = + new InteractiveRequest(requestParameters, extraScopesToConsent, loginHint, UIBehavior.SelectAccount, null); + return await handler.CreateAuthorizationUriAsync().ConfigureAwait(false); + } + + internal ClientCredential ClientCredential { get; } + + internal TokenCache AppTokenCache { get; } + + private async Task AcquireTokenForClientCommonAsync(IEnumerable scopes, bool forceRefresh, ApiEvent.ApiIds apiId) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + AuthenticationRequestParameters parameters = CreateRequestParameters(authority, scopes, null, + AppTokenCache); + parameters.IsClientCredentialRequest = true; + var handler = new ClientCredentialRequest(parameters, forceRefresh) { ApiId = apiId, IsConfidentialClient = true }; + return await handler.RunAsync().ConfigureAwait(false); + } + + private async Task AcquireTokenOnBehalfCommonAsync(Authority authority, + IEnumerable scopes, UserAssertion userAssertion, ApiEvent.ApiIds apiId) + { + var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); + requestParams.UserAssertion = userAssertion; + var handler = new OnBehalfOfRequest(requestParams) { ApiId = apiId, IsConfidentialClient = true }; + return await handler.RunAsync().ConfigureAwait(false); + } + + private async Task AcquireTokenByAuthorizationCodeCommonAsync(string authorizationCode, + IEnumerable scopes, Uri redirectUri, ApiEvent.ApiIds apiId) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); + requestParams.AuthorizationCode = authorizationCode; + requestParams.RedirectUri = redirectUri; + var handler = + new AuthorizationCodeRequest(requestParams) { ApiId = apiId, IsConfidentialClient = true }; + return await handler.RunAsync().ConfigureAwait(false); + } + + internal override AuthenticationRequestParameters CreateRequestParameters(Authority authority, IEnumerable scopes, IUser user, TokenCache cache) + { + AuthenticationRequestParameters parameters = base.CreateRequestParameters(authority, scopes, user, cache); + parameters.ClientId = ClientId; + //parameters.ClientCredential = ClientCredential; + + return parameters; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta new file mode 100644 index 0000000..60004a4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 105ce650a2c65814eb36c0fecb04f442 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs new file mode 100644 index 0000000..2416021 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client +{ + /// + /// Component to be used for confidential client applications like Web Apps/API. + /// + public interface IConfidentialClientApplication : IClientApplicationBase + { + /// + /// Acquires token using On-Behalf-Of flow. + /// + /// Array of scopes requested for resource + /// Instance of UserAssertion containing user's token. + /// Authentication result containing token of the user for the requested scopes + Task AcquireTokenOnBehalfOfAsync( + IEnumerable scopes, + UserAssertion userAssertion); + + /// + /// Acquires token using On-Behalf-Of flow. + /// + /// Array of scopes requested for resource + /// Instance of UserAssertion containing user's token. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user for the requested scopes + Task AcquireTokenOnBehalfOfAsync( + IEnumerable scopes, + UserAssertion userAssertion, + string authority); + + /// + /// Acquires security token from the authority using authorization code previously received. + /// This method does not lookup token cache, but stores the result in it, so it can be looked up using other methods such as . + /// + /// The authorization code received from service authorization endpoint. + /// Array of scopes requested for resource + /// Authentication result containing token of the user for the requested scopes + Task AcquireTokenByAuthorizationCodeAsync( + string authorizationCode, + IEnumerable scopes); + + /// + /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. + /// + /// Array of scopes requested for resource + /// Authentication result containing application token for the requested scopes + Task AcquireTokenForClientAsync( + IEnumerable scopes); + + /// + /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. + /// + /// Array of scopes requested for resource + /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using client credentials + /// Authentication result containing application token for the requested scopes + Task AcquireTokenForClientAsync( + IEnumerable scopes, + bool forceRefresh); + + /// + /// Gets URL of the authorize endpoint including the query parameters. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// URL of the authorize endpoint including the query parameters. + Task GetAuthorizationRequestUrlAsync( + IEnumerable scopes, + string loginHint, + string extraQueryParameters); + + /// + /// Gets URL of the authorize endpoint including the query parameters. + /// + /// Array of scopes requested for resource + /// Address to return to upon receiving a response from the authority. + /// Identifier of the user. Generally a UPN. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// URL of the authorize endpoint including the query parameters. + Task GetAuthorizationRequestUrlAsync( + IEnumerable scopes, + string redirectUri, + string loginHint, + string extraQueryParameters, IEnumerable extraScopesToConsent, string authority); + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta new file mode 100644 index 0000000..b13f58d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 549c2f58fa622d24b95b97f8dd0eb416 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs new file mode 100644 index 0000000..4ce3edf --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs @@ -0,0 +1,225 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client; +using System; +using System.Runtime.Serialization; +using System.Text; + +namespace Microsoft.Identity.Client.Internal.Jwt +{ + internal class JsonWebTokenConstants + { + public const uint JwtToAadLifetimeInSeconds = 60*10; // Ten minutes + public const string HeaderType = "JWT"; + + internal class Algorithms + { + public const string RsaSha256 = "RS256"; + public const string None = "none"; + } + + internal class ReservedClaims + { + public const string Audience = "aud"; + public const string Issuer = "iss"; + public const string Subject = "sub"; + public const string NotBefore = "nbf"; + public const string ExpiresOn = "exp"; + public const string JwtIdentifier = "jti"; + } + + internal class ReservedHeaderParameters + { + public const string Algorithm = "alg"; + public const string Type = "typ"; + public const string X509CertificateThumbprint = "kid"; + } + } + + internal class JsonWebToken + { + // (64K) This is an arbitrary large value for the token length. We can adjust it as needed. + private const int MaxTokenLength = 65536; + public readonly JWTPayload Payload; + + public JsonWebToken(string clientId, string audience) + { + DateTime validFrom = DateTime.UtcNow; + + DateTime validTo = validFrom + TimeSpan.FromSeconds(JsonWebTokenConstants.JwtToAadLifetimeInSeconds); + + Payload = new JWTPayload + { + Audience = audience, + Issuer = clientId, + ValidFrom = ConvertToTimeT(validFrom), + ValidTo = ConvertToTimeT(validTo), + Subject = clientId, + JwtIdentifier = Guid.NewGuid().ToString() + }; + } + + public string Sign(ClientAssertionCertificate credential) + { + // Base64Url encoded header and claims + string token = Encode(credential); + + // Length check before sign + if (MaxTokenLength < token.Length) + { + throw new MsalException(MsalError.EncodedTokenTooLong); + } + + return string.Concat(token, ".", UrlEncodeSegment(credential.Sign(token))); + } + + private static string EncodeSegment(string segment) + { + return UrlEncodeSegment(Encoding.UTF8.GetBytes(segment)); + } + + private static string UrlEncodeSegment(byte[] segment) + { + return Base64UrlHelpers.Encode(segment); + } + + private static string EncodeHeaderToJson(ClientAssertionCertificate credential) + { + JWTHeaderWithCertificate header = new JWTHeaderWithCertificate(credential); + return JsonHelper.SerializeToJson(header); + } + + internal static long ConvertToTimeT(DateTime time) + { + var startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); + TimeSpan diff = time - startTime; + return (long) (diff.TotalSeconds); + } + + private string Encode(ClientAssertionCertificate credential) + { + // Header segment + string jsonHeader = EncodeHeaderToJson(credential); + + string encodedHeader = EncodeSegment(jsonHeader); + + // Payload segment + string jsonPayload = JsonHelper.SerializeToJson(Payload); + + string encodedPayload = EncodeSegment(jsonPayload); + + return string.Concat(encodedHeader, ".", encodedPayload); + } + + [DataContract] + internal class JWTHeader + { + public JWTHeader(ClientAssertionCertificate credential) + { + Credential = credential; + } + + protected ClientAssertionCertificate Credential { get; } + + [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.Type)] + public static string Type + { + get { return JsonWebTokenConstants.HeaderType; } + + set + { + // This setter is required by DataContractJsonSerializer + } + } + + [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.Algorithm)] + public string Algorithm + { + get + { + return Credential == null + ? JsonWebTokenConstants.Algorithms.None + : JsonWebTokenConstants.Algorithms.RsaSha256; + } + + set + { + // This setter is required by DataContractJsonSerializer + } + } + } + + [DataContract] + internal class JWTPayload + { + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Audience)] + public string Audience { get; set; } + + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Issuer)] + public string Issuer { get; set; } + + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.NotBefore)] + public long ValidFrom { get; set; } + + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.ExpiresOn)] + public long ValidTo { get; set; } + + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Subject, IsRequired = false, + EmitDefaultValue = false)] + public string Subject { get; set; } + + [DataMember(Name = JsonWebTokenConstants.ReservedClaims.JwtIdentifier, IsRequired = false, + EmitDefaultValue = false)] + public string JwtIdentifier { get; set; } + } + + [DataContract] + internal sealed class JWTHeaderWithCertificate : JWTHeader + { + public JWTHeaderWithCertificate(ClientAssertionCertificate credential) + : base(credential) + { + } + + [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.X509CertificateThumbprint)] + public string X509CertificateThumbprint + { + get + { + // Thumbprint should be url encoded + return Credential.Thumbprint; + } + + set + { + // This setter is required by DataContractJsonSerializer + } + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta new file mode 100644 index 0000000..f32b241 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7e486512ab0902468a90c835c205dd5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta new file mode 100644 index 0000000..4f2bd53 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 332af1b833a8db848b0aa4af906bdf93 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs new file mode 100644 index 0000000..2b0f8c4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Diagnostics.Tracing; + +namespace Microsoft.Identity.Client.Internal.EventsSource +{ + [EventSource(Name = "Microsoft.Identity.Client")] + internal class MsalEventSource : EventSource + { + [Event(1, Level = EventLevel.Verbose)] + internal void Verbose(string message) + { + WriteEvent(1, message); + } + + [Event(2, Level = EventLevel.Informational)] + internal void Information(string message) + { + WriteEvent(2, message); + } + + [Event(3, Level = EventLevel.Warning)] + internal void Warning(string message) + { + WriteEvent(3, message); + } + + [Event(4, Level = EventLevel.Error)] + internal void Error(string message) + { + WriteEvent(4, message); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta new file mode 100644 index 0000000..e464d0a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc069cabc75b0114c9db963e813bc218 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs new file mode 100644 index 0000000..9009c20 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client.Internal.EventsSource +{ + internal class PlatformLogger : ILogger + { + static PlatformLogger() + { + MsalEventSource = new MsalEventSource(); + } + + internal static MsalEventSource MsalEventSource { get; } + + public void Error(string message) + { + MsalEventSource.Error(message); + } + + public void Warning(string message) + { + MsalEventSource.Error(message); + } + + public void Verbose(string message) + { + MsalEventSource.Error(message); + } + + public void Information(string message) + { + MsalEventSource.Error(message); + } + + public void Error(Exception ex) + { + Error(ex.ToString()); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta new file mode 100644 index 0000000..3605d3e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ffe51c4e4d020e4cb510d1f9a6e429d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta new file mode 100644 index 0000000..55eddd8 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ae6cb4ef844bc9b46b320747d7376ab4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs new file mode 100644 index 0000000..123d411 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client +{ + public sealed partial class PublicClientApplication : ClientApplicationBase + { + + /// + /// Constructor to create application instance. This constructor is only available for Desktop and NetCore apps + /// + /// Client id of the application + /// Default authority to be used for the application + /// Instance of TokenCache. + public PublicClientApplication(string clientId, string authority, TokenCache userTokenCache) : base(clientId, + authority, PlatformPlugin.PlatformInformation.GetDefaultRedirectUri(clientId), true) + { + UserTokenCache = userTokenCache; + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta new file mode 100644 index 0000000..8ee834d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38db533a629e2e7478019095597d6f9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta new file mode 100644 index 0000000..e008a2e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d050d96e022f4d3478e4f34a8d4ae203 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs new file mode 100644 index 0000000..3d40e78 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs @@ -0,0 +1,115 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using System.Linq; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Cache; + +namespace Microsoft.Identity.Client +{ + internal class TokenCacheAccessor : ITokenCacheAccessor + { + internal readonly IDictionary AccessTokenCacheDictionary = + new ConcurrentDictionary(); + + internal readonly IDictionary RefreshTokenCacheDictionary = + new ConcurrentDictionary(); + + public void SaveAccessToken(string cacheKey, string item) + { + AccessTokenCacheDictionary[cacheKey] = item; + } + + public void SaveRefreshToken(string cacheKey, string item) + { + RefreshTokenCacheDictionary[cacheKey] = item; + } + + public string GetRefreshToken(string refreshTokenKey) + { + if (!RefreshTokenCacheDictionary.ContainsKey(refreshTokenKey)) + { + return null; + } + + return RefreshTokenCacheDictionary[refreshTokenKey]; + } + + public void DeleteAccessToken(string cacheKey) + { + AccessTokenCacheDictionary.Remove(cacheKey); + } + + public void DeleteRefreshToken(string cacheKey) + { + RefreshTokenCacheDictionary.Remove(cacheKey); + } + + public ICollection GetAllAccessTokensAsString() + { + return + new ReadOnlyCollection( + AccessTokenCacheDictionary.Values.ToList()); + } + + public ICollection GetAllRefreshTokensAsString() + { + return + new ReadOnlyCollection( + RefreshTokenCacheDictionary.Values.ToList()); + } + + public ICollection GetAllAccessTokenKeys() + { + return + new ReadOnlyCollection( + AccessTokenCacheDictionary.Keys.ToList()); + } + + public ICollection GetAllRefreshTokenKeys() + { + return + new ReadOnlyCollection( + RefreshTokenCacheDictionary.Keys.ToList()); + } + + public void Clear() + { + foreach (var key in GetAllAccessTokenKeys()) + { + DeleteAccessToken(key); + } + + foreach (var key in GetAllRefreshTokenKeys()) + { + DeleteRefreshToken(key); + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta new file mode 100644 index 0000000..8ea94ba --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecafd7540c09b864599d7868c2ee3e80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs new file mode 100644 index 0000000..eda9888 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs @@ -0,0 +1,125 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Cache; + +namespace Microsoft.Identity.Client +{ + /// + /// + /// + public static class TokenCacheExtensions + { + /// + /// + /// + /// + /// + public static void SetBeforeAccess(this TokenCache tokencache, TokenCache.TokenCacheNotification beforeAccess) + { + tokencache.BeforeAccess = beforeAccess; + } + + /// + /// + /// + /// + /// + public static void SetAfterAccess(this TokenCache tokencache, TokenCache.TokenCacheNotification afterAccess) + { + tokencache.AfterAccess = afterAccess; + } + + /// + /// + /// + /// + /// + public static void SetBeforeWrite(this TokenCache tokencache, TokenCache.TokenCacheNotification beforeWrite) + { + tokencache.BeforeWrite = beforeWrite; + } + + /// + /// + /// + /// + /// + public static void Deserialize(this TokenCache tokenCache, byte[] state) + { + lock (tokenCache.LockObject) + { + RequestContext requestContext = new RequestContext(Guid.Empty, null); + Dictionary> cacheDict = JsonHelper + .DeserializeFromJson>>(state); + if (cacheDict == null || cacheDict.Count == 0) + { + //TODO log about empty cache + return; + } + + if (cacheDict.ContainsKey("access_tokens")) + { + foreach (var atItem in cacheDict["access_tokens"]) + { + tokenCache.AddAccessTokenCacheItem(JsonHelper.DeserializeFromJson(atItem)); + } + } + + if (cacheDict.ContainsKey("refresh_tokens")) + { + foreach (var rtItem in cacheDict["refresh_tokens"]) + { + tokenCache.AddRefreshTokenCacheItem(JsonHelper.DeserializeFromJson(rtItem)); + } + } + } + } + + /// + /// + /// + /// + /// + public static byte[] Serialize(this TokenCache tokenCache) + { + // reads the underlying in-memory dictionary and dumps out the content as a JSON + lock (tokenCache.LockObject) + { + RequestContext requestContext = new RequestContext(Guid.Empty, null); + Dictionary> cacheDict = new Dictionary>(); + cacheDict["access_tokens"] = tokenCache.GetAllAccessTokenCacheItems(requestContext); + cacheDict["refresh_tokens"] = tokenCache.GetAllRefreshTokenCacheItems(requestContext); + return JsonHelper.SerializeToJson(cacheDict).ToByteArray(); + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta new file mode 100644 index 0000000..960c3f5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdbdc632ab443be43973089b7fd094e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs new file mode 100644 index 0000000..ccd8e21 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs @@ -0,0 +1,115 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client +{ + /// + /// Component containing common validation methods + /// + public interface IClientApplicationBase + { + /// + /// Identifier of the component consuming MSAL and it is intended for libraries/SDKs that consume MSAL. This will allow for + /// disambiguation between MSAL usage by the app vs MSAL usage by component libraries. + /// + string Component { get; set; } + + /// + /// Authority provided by the developer or default authority used by the library. + /// + string Authority { get; } + + /// + /// Will be a default value. Can be overridden by the developer. Once set, application will bind to the client Id. + /// + string ClientId { get; } + + /// + /// Redirect Uri configured in the portal. Will have a default value. Not required if the developer is using the + /// default client Id. + /// + string RedirectUri { get; set; } + + /// + /// Gets a value indicating whether address validation is ON or OFF. + /// + bool ValidateAuthority { get; } + + /// + /// Returns a user-centric view over the cache that provides a list of all the available users in the cache. + /// + IEnumerable Users { get; } + + /// + /// Sets or Gets the custom query parameters that may be sent to the STS for dogfood testing. This parameter should not be set by the + /// developers as it may have adverse effect on the application. + /// + string SliceParameters { get; set; } + + /// + /// Get user by identifier from users available in the cache. + /// + /// user identifier + IUser GetUser(string identifier); + + /// + /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. + /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or + /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. + /// + /// Array of scopes requested for resource + /// User for which the token is requested. + Task AcquireTokenSilentAsync( + IEnumerable scopes, + IUser user); + + /// + /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. + /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or + /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. + /// + /// Array of scopes requested for resource + /// User for which the token is requested + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using the refresh token if available + Task AcquireTokenSilentAsync( + IEnumerable scopes, + IUser user, + string authority, + bool forceRefresh); + + /// + /// Removes all cached tokens for the specified user. + /// + /// instance of the user that needs to be removed + void Remove(IUser user); + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta new file mode 100644 index 0000000..8def2fd --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e860bfdc4d7950468f027061ec0ba01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs new file mode 100644 index 0000000..5701233 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs @@ -0,0 +1,240 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client +{ + /// + /// Component to be used for native applications (Desktop/UWP/iOS/Android). + /// + public interface IPublicClientApplication : IClientApplicationBase + { + +#if WINRT + /// + /// + /// + bool UseCorporateNetwork { get; set; } +#endif + + // expose the interactive API without UIParent only for platforms that + // do not need it to operate like desktop, UWP, iOS. +#if !ANDROID + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Authentication result containing token of the user + Task AcquireTokenAsync(IEnumerable scopes); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint, + UIBehavior behavior, + string extraQueryParameters); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, + UIBehavior behavior, + string extraQueryParameters); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint, + UIBehavior behavior, + string extraQueryParameters, + IEnumerable extraScopesToConsent, string authority); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, + UIBehavior behavior, + string extraQueryParameters, + IEnumerable extraScopesToConsent, + string authority); + +#endif + + // these API methods are exposed on other platforms. + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync(IEnumerable scopes, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint, + UIBehavior behavior, + string extraQueryParameters, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, + UIBehavior behavior, + string extraQueryParameters, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + string loginHint, + UIBehavior behavior, + string extraQueryParameters, + IEnumerable extraScopesToConsent, string authority, UIParent parent); + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, + UIBehavior behavior, + string extraQueryParameters, + IEnumerable extraScopesToConsent, + string authority, UIParent parent); + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta new file mode 100644 index 0000000..3a2cc50 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe598b4394878774fa9349ed3719a0bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs new file mode 100644 index 0000000..3b659e0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client +{ + /// + /// Contains information of a single user. This information is used for token cache lookup and enforcing the user session on STS authorize endpont. + /// + public interface IUser + { + /// + /// Gets a displayable value in UserPrincipalName (UPN) format. The value can be null. + /// + string DisplayableId { get; } + + /// + /// Gets given name of the user if provided by the service. If not, the value is null. + /// + string Name { get; } + + /// + /// Gets identity provider if returned by the service. If not, the value is null. + /// + string IdentityProvider { get; } + + /// + /// Gets an identifier for the user that is used by the library and the service as a strong handle to user identity. Cannot be null. + /// + string Identifier { get; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta new file mode 100644 index 0000000..b5b1d98 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 609e2142a21058f489c0f4847697b8c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta new file mode 100644 index 0000000..940a39b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f28e821199708264782c242025140e67 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs new file mode 100644 index 0000000..5e7fd00 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs @@ -0,0 +1,124 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal +{ + internal enum AuthorizationStatus + { + Success, + ErrorHttp, + ProtocolError, + UserCancel, + UnknownError + } + + internal class AuthorizationResult + { + internal AuthorizationResult(AuthorizationStatus status, string returnedUriInput) : this(status) + { + if (Status == AuthorizationStatus.UserCancel) + { + Error = MsalClientException.AuthenticationCanceledError; + ErrorDescription = MsalErrorMessage.AuthenticationCanceled; + } + else if (Status == AuthorizationStatus.UnknownError) + { + Error = MsalException.UnknownError; + ErrorDescription = MsalErrorMessage.Unknown; + } + else + { + ParseAuthorizeResponse(returnedUriInput); + } + } + + internal AuthorizationResult(AuthorizationStatus status) + { + Status = status; + } + + public AuthorizationStatus Status { get; private set; } + + public string Code { get; private set; } + + public string Error { get; set; } + + public string ErrorDescription { get; set; } + + public string State { get; set; } + + public void ParseAuthorizeResponse(string webAuthenticationResult) + { + var resultUri = new Uri(webAuthenticationResult); + + // NOTE: The Fragment property actually contains the leading '#' character and that must be dropped + string resultData = resultUri.Query; + + if (!string.IsNullOrWhiteSpace(resultData)) + { + // Remove the leading '?' first + Dictionary response = MsalHelpers.ParseKeyValueList(resultData.Substring(1), '&', + true, null); + + if (response.ContainsKey(OAuth2Parameter.State)) + { + State = response[OAuth2Parameter.State]; + } + + if (response.ContainsKey(TokenResponseClaim.Code)) + { + Code = response[TokenResponseClaim.Code]; + } + else if (response.ContainsKey(TokenResponseClaim.Error)) + { + Error = response[TokenResponseClaim.Error]; + ErrorDescription = response.ContainsKey(TokenResponseClaim.ErrorDescription) + ? response[TokenResponseClaim.ErrorDescription] + : null; + Status = AuthorizationStatus.ProtocolError; + } + else + { + Error = MsalError.AuthenticationFailed; + ErrorDescription = MsalErrorMessage.AuthorizationServerInvalidResponse; + Status = AuthorizationStatus.UnknownError; + } + } + else + { + Error = MsalError.AuthenticationFailed; + ErrorDescription = MsalErrorMessage.AuthorizationServerInvalidResponse; + Status = AuthorizationStatus.UnknownError; + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta new file mode 100644 index 0000000..d3bc826 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5436665cad532a249bd4336071119969 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs new file mode 100644 index 0000000..0e1d3b3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using System.Text; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class Base64UrlHelpers + { + private const char Base64PadCharacter = '='; + private const char Base64Character62 = '+'; + private const char Base64Character63 = '/'; + private const char Base64UrlCharacter62 = '-'; + private const char Base64UrlCharacter63 = '_'; + private static readonly Encoding TextEncoding = Encoding.UTF8; + + private static readonly string DoubleBase64PadCharacter = string.Format(CultureInfo.InvariantCulture, "{0}{0}", + Base64PadCharacter); + + // + // The following functions perform base64url encoding which differs from regular base64 encoding as follows + // * padding is skipped so the pad character '=' doesn't have to be percent encoded + // * the 62nd and 63rd regular base64 encoding characters ('+' and '/') are replace with ('-' and '_') + // The changes make the encoding alphabet file and URL safe + // See RFC4648, section 5 for more info + // + public static string Encode(string arg) + { + if (arg == null) + { + return null; + } + + return Encode(TextEncoding.GetBytes(arg)); + } + + public static string DecodeToString(string arg) + { + byte[] decoded = DecodeToBytes(arg); + return MsalHelpers.CreateString(decoded); + } + + public static byte[] DecodeToBytes(string arg) + { + string s = arg; + s = s.Replace(Base64UrlCharacter62, Base64Character62); // 62nd char of encoding + s = s.Replace(Base64UrlCharacter63, Base64Character63); // 63rd char of encoding + + switch (s.Length%4) + { + // Pad + case 0: + break; // No pad chars in this case + case 2: + s += DoubleBase64PadCharacter; + break; // Two pad chars + case 3: + s += Base64PadCharacter; + break; // One pad char + default: + throw new ArgumentException("Illegal base64url string!", nameof(arg)); + } + + return Convert.FromBase64String(s); // Standard base64 decoder + } + + internal static string Encode(byte[] arg) + { + if (arg == null) + { + return null; + } + + string s = Convert.ToBase64String(arg); + s = s.Split(Base64PadCharacter)[0]; // Remove any trailing padding + s = s.Replace(Base64Character62, Base64UrlCharacter62); // 62nd char of encoding + s = s.Replace(Base64Character63, Base64UrlCharacter63); // 63rd char of encoding + + return s; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta new file mode 100644 index 0000000..b665f84 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 872b6724b79420c4b974b99e739913cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta new file mode 100644 index 0000000..988125a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f8f985ee5c770d54fae506579acef4ff +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs new file mode 100644 index 0000000..7b084e5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs @@ -0,0 +1,140 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + [DataContract] + internal class AccessTokenCacheItem : BaseTokenCacheItem + { + public AccessTokenCacheItem() + { + } + + public AccessTokenCacheItem(string authority, string clientId, TokenResponse response) + : base(clientId) + { + + TokenType = response.TokenType; + Scope = response.Scope; + Authority = authority; + if (response.AccessToken != null) + { + AccessToken = response.AccessToken; + ExpiresOnUnixTimestamp = MsalHelpers.DateTimeToUnixTimestamp(response.AccessTokenExpiresOn); + } + + RawClientInfo = response.ClientInfo; + RawIdToken = response.IdToken; + CreateDerivedProperties(); + } + + /// + /// Gets the AccessToken Type. + /// + [DataMember(Name = "token_type")] + public string TokenType { get; set; } + + /// + /// Gets the Access Token requested. + /// + [DataMember(Name = "access_token")] + public string AccessToken { get; set; } + + [DataMember(Name = "id_token")] + public string RawIdToken { get; set; } + + [DataMember(Name = "expires_on")] + public long ExpiresOnUnixTimestamp { get; set; } + + /// + /// Gets the Authority. + /// + [DataMember(Name = "authority")] + public string Authority { get; set; } + + /// + /// Gets the ScopeSet. + /// + [DataMember(Name = "scope")] + public string Scope { get; set; } + + [DataMember(Name = "user_assertion_hash")] + public string UserAssertionHash { get; set; } + + public SortedSet ScopeSet { get; set; } + + public IdToken IdToken { get; set; } + + public DateTimeOffset ExpiresOn + { + get + { + DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + return dtDateTime.AddSeconds(ExpiresOnUnixTimestamp).ToUniversalTime(); + } + set + { + DateTimeOffset ignored = value; + } + } + + public AccessTokenCacheKey GetAccessTokenItemKey() + { + return new AccessTokenCacheKey(Authority, ScopeSet, ClientId, GetUserIdentifier()); + } + + private void CreateDerivedProperties() + { + ScopeSet = Scope.AsSet(); + IdToken = IdToken.Parse(RawIdToken); + if (!string.IsNullOrEmpty(RawClientInfo)) + { + // this should only happen for client credentials. + ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); + } + + if (IdToken != null) + { + User = new User(GetUserIdentifier(), IdToken.PreferredUsername, IdToken.Name, IdToken.Issuer); + } + } + + // This method is called after the object + // is completely deserialized. + [OnDeserialized] + void OnDeserialized(StreamingContext context) + { + CreateDerivedProperties(); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta new file mode 100644 index 0000000..ddc91a5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94aef809369c54f479cd3e2fb0808868 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs new file mode 100644 index 0000000..6a964eb --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs @@ -0,0 +1,88 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + /// + /// + /// + internal class AccessTokenCacheKey : TokenCacheKeyBase + { + public AccessTokenCacheKey(string authority, SortedSet scopes, string clientId, string userIdentifier) : base(clientId, userIdentifier) + { + Authority = authority; + Scope = scopes ?? new SortedSet(); + } + + public string Authority { get; } + + public SortedSet Scope { get; } + + /// + /// + /// + public override string ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(Base64UrlHelpers.Encode(Authority)); + stringBuilder.Append(CacheKeyDelimiter); + stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); + stringBuilder.Append(CacheKeyDelimiter); + // scope is treeSet to guarantee the order of the scopes when converting to string. + stringBuilder.Append(Base64UrlHelpers.Encode(Scope.AsSingleString())); + stringBuilder.Append(CacheKeyDelimiter); + stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); + + return stringBuilder.ToString(); + } + + internal bool ScopeEquals(SortedSet otherScope) + { + if (Scope == null) + { + return otherScope == null; + } + + if (otherScope == null) + { + return Scope == null; + } + + if (Scope.Count == otherScope.Count) + { + return Scope.Intersect(otherScope, StringComparer.OrdinalIgnoreCase).Count() == Scope.Count; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta new file mode 100644 index 0000000..6762d57 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6af361badd3c0504188c3f0802d5093e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs new file mode 100644 index 0000000..b6a10af --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Globalization; +using System.Runtime.Serialization; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + /// + /// Token cache item + /// + [DataContract] + internal abstract class BaseTokenCacheItem + { + private const int CacheVersion = 1; + + /// + /// Default constructor. + /// + public BaseTokenCacheItem(string clientId) + { + ClientId = clientId; + } + + public BaseTokenCacheItem() + { + } + + [DataMember(Name = "ver", IsRequired = false)] + public int Version { get; set; } = CacheVersion; + + [DataMember(Name = "client_info")] + public string RawClientInfo { get; set; } + + [DataMember(Name = "client_id")] + public string ClientId { get; set; } + + public ClientInfo ClientInfo { get; set; } + + public User User { get; set; } + + internal string GetUserIdentifier() + { + return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", Base64UrlHelpers.Encode(ClientInfo?.UniqueIdentifier), + Base64UrlHelpers.Encode(ClientInfo?.UniqueTenantIdentifier)); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta new file mode 100644 index 0000000..4734a63 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 081099b0b48a9964dbb81f6d2d96fe3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs new file mode 100644 index 0000000..0712e4c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + internal interface ITokenCacheAccessor + { + void SaveAccessToken(string cacheKey, string item); + + void SaveRefreshToken(string cacheKey, string item); + + string GetRefreshToken(string refreshTokenKey); + + void DeleteAccessToken(string cacheKey); + + void DeleteRefreshToken(string cacheKey); + + ICollection GetAllAccessTokensAsString(); + + ICollection GetAllRefreshTokensAsString(); + + ICollection GetAllAccessTokenKeys(); + + ICollection GetAllRefreshTokenKeys(); + + void Clear(); + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta new file mode 100644 index 0000000..8760ca2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 159657aa35708494ebe728baacfa9ae2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs new file mode 100644 index 0000000..08e998d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs @@ -0,0 +1,95 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Globalization; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + [DataContract] + internal class RefreshTokenCacheItem : BaseTokenCacheItem + { + + public RefreshTokenCacheItem() + { + } + + public RefreshTokenCacheItem(string environment, string clientId, TokenResponse response) : base(clientId) + { + RefreshToken = response.RefreshToken; + Environment = environment; + PopulateIdentifiers(response); + } + + [DataMember(Name = "environment")] + public string Environment { get; set; } + + [DataMember(Name = "displayable_id")] + public string DisplayableId { get; internal set; } + + [DataMember(Name = "name")] + public string Name { get; internal set; } + + [DataMember(Name = "identity_provider")] + public string IdentityProvider { get; internal set; } + + [DataMember (Name = "refresh_token")] + public string RefreshToken { get; set; } + + public RefreshTokenCacheKey GetRefreshTokenItemKey() + { + return new RefreshTokenCacheKey(Environment, ClientId, GetUserIdentifier()); + } + + public void PopulateIdentifiers(TokenResponse response) + { + IdToken idToken = IdToken.Parse(response.IdToken); + RawClientInfo = response.ClientInfo; + ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); + + DisplayableId = idToken.PreferredUsername; + Name = idToken.Name; + IdentityProvider = idToken.Issuer; + + User = new User(GetUserIdentifier(), DisplayableId, Name, IdentityProvider); + } + + // This method is called after the object + // is completely deserialized. + [OnDeserialized] + void OnDeserialized(StreamingContext context) + { + if (!string.IsNullOrEmpty(RawClientInfo)) + { + ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); + } + + User = new User(GetUserIdentifier(), DisplayableId, Name, IdentityProvider); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta new file mode 100644 index 0000000..4d28e23 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22d4899d37896e1438f3b05292c2cbb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs new file mode 100644 index 0000000..565b6b0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs @@ -0,0 +1,57 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Text; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + class RefreshTokenCacheKey : TokenCacheKeyBase + { + + public RefreshTokenCacheKey(string environment, string clientId, string userIdentifier) : base(clientId, userIdentifier) + { + Environment = environment; + } + + public string Environment { get; } + + /// + /// + /// + public override string ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(Base64UrlHelpers.Encode(Environment)); + stringBuilder.Append(CacheKeyDelimiter); + stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); + stringBuilder.Append(CacheKeyDelimiter); + stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); + + return stringBuilder.ToString(); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta new file mode 100644 index 0000000..48d2c59 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2960a823130dd441a912072a1209385 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs new file mode 100644 index 0000000..ec069bf --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs @@ -0,0 +1,51 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client.Internal.Cache +{ + internal abstract class TokenCacheKeyBase + { + public const string CacheKeyDelimiter = "$"; + + public TokenCacheKeyBase(string clientId, string userIdentifier) + { + ClientId = clientId; + UserIdentifier = userIdentifier; + } + + public string ClientId { get; set; } + + public string UserIdentifier { get; set; } + + protected bool Equals(string string1, string string2) + { + return (string.Compare(string2, string1, StringComparison.OrdinalIgnoreCase) == 0); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta new file mode 100644 index 0000000..2dc21df --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6955c3f33cdcdd49aa5d67d2d515930 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs new file mode 100644 index 0000000..aa7a960 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs @@ -0,0 +1,86 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.Identity.Client.Internal +{ + internal class ClientInfoClaim + { + public const string UniqueIdentifier = "uid"; + public const string UnqiueTenantIdentifier = "utid"; + } + + [DataContract] + internal class ClientInfo + { + [DataMember(Name = ClientInfoClaim.UniqueIdentifier, IsRequired = false)] + public string UniqueIdentifier { get; set; } + + [DataMember(Name = ClientInfoClaim.UnqiueTenantIdentifier, IsRequired = false)] + public string UniqueTenantIdentifier { get; set; } + + public static ClientInfo CreateFromJson(string clientInfo) + { + if (string.IsNullOrEmpty(clientInfo)) + { + throw new MsalClientException(MsalClientException.JsonParseError, "client info is null"); + } + + try + { + return JsonHelper.DeserializeFromJson(Base64UrlHelpers.DecodeToBytes(clientInfo)); + } + catch (Exception exc) + { + throw new MsalClientException(MsalClientException.JsonParseError, + "Failed to parse the returned client info.", exc); + } + } + public static ClientInfo CreateFromEncodedString(string encodedUserIdentiier) + { + if (string.IsNullOrEmpty(encodedUserIdentiier)) + { + return null; + } + + string[] artifacts = encodedUserIdentiier.Split('.'); + + if (artifacts.Length == 0) + { + return null; + } + + return new ClientInfo() + { + UniqueIdentifier = Base64UrlHelpers.DecodeToString(artifacts[0]), + UniqueTenantIdentifier = Base64UrlHelpers.DecodeToString(artifacts[1]), + }; + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta new file mode 100644 index 0000000..3a7a328 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e3ebe8a6ea08024fa51eec8d8eb7d95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs new file mode 100644 index 0000000..f64e876 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs @@ -0,0 +1,202 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Xml.Linq; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class MsalErrorEx + { + public const string UnauthorizedUserInformationAccess = "unauthorized_user_information_access"; + public const string CannotAccessUserInformation = "user_information_access_failed"; + public const string NeedToSetCallbackUriAsLocalSetting = "need_to_set_callback_uri_as_local_setting"; + public const string DeviceCodeAuthorizationPendingError = "authorization_pending"; + } + + internal static class MsalErrorMessageEx + { + public const string CannotAccessUserInformation = + "Cannot access user information. Check machine's Privacy settings or initialize UserCredential with userId"; + + public const string UnauthorizedUserInformationAccess = + "Unauthorized accessing user information. Check application's 'Enterprise Authentication' capability"; + + public const string NeedToSetCallbackUriAsLocalSetting = + "You need to add the value of WebAuthenticationBroker.GetCurrentApplicationCallbackUri() to an application's local setting named CurrentApplicationCallbackUri."; + } + + internal static class Constants + { + public const string MsAppScheme = "ms-app"; + public static readonly Uri SsoPlaceHolderUri = new Uri("https://sso"); + public const int ExpirationMarginInMinutes = 5; + public const int CodeVerifierLength = 128; + public const int CodeVerifierByteSize = 32; + } + + + /// + /// The active directory authentication error message. + /// + internal static class MsalErrorMessage + { + public const string AccessingMetadataDocumentFailed = "Accessing WS metadata exchange failed"; + + public const string AssemblyNotFoundTemplate = + "Assembly required for the platform not found. Make sure assembly '{0}' exists"; + + public const string AssemblyLoadFailedTemplate = + "Loading an assembly required for the platform failed. Make sure assembly for the correct platform '{0}' exists"; + + public const string NonHttpsRedirectNotSupported = "Non-HTTPS url redirect is not supported in webview"; + public const string AuthenticationUiFailed = "The browser based authentication dialog failed to complete"; + public const string AuthorityInvalidUriFormat = "'authority' should be in Uri format"; + public const string AuthorityNotSupported = "'authority' is not supported"; + public const string DeprecatedAuthorityError = "login.windows.net has been deprecated. Use login.microsoftonline.com instead."; + public const string AuthorityValidationFailed = "Authority validation failed"; + public const string AuthorityUriInsecure = "'authority' should use the 'https' scheme"; + + public const string B2cAuthorityUriInvalidPath = + "B2C 'authority' Uri should have at least 3 segments in the path (i.e. https:///tfp///...)"; + public const string AuthorityUriInvalidPath = + "'authority' Uri should have at least one segment in the path (i.e. https:////...)"; + + public const string AuthorizationServerInvalidResponse = "The authorization server returned an invalid response"; + + public const string CertificateKeySizeTooSmallTemplate = + "The certificate used must have a key size of at least {0} bits"; + + public const string EmailAddressSuffixMismatch = + "No identity provider email address suffix matches the provided address"; + + public const string EncodedTokenTooLong = "Encoded token size is beyond the upper limit"; + public const string FailedToAcquireTokenSilently = "Failed to acquire token silently. Call method AcquireToken"; + public const string FailedToRefreshToken = "Failed to refresh token"; + public const string FederatedServiceReturnedErrorTemplate = "Federated service at {0} returned error: {1}"; + public const string IdentityProtocolLoginUrlNull = "The LoginUrl property in identityProvider cannot be null"; + public const string IdentityProtocolMismatch = "No identity provider matches the requested protocol"; + + public const string IdentityProviderRequestFailed = + "Token request to identity provider failed. Check InnerException for more details"; + + public const string InvalidArgumentLength = "Parameter has invalid length"; + public const string InvalidAuthenticateHeaderFormat = "Invalid authenticate header format"; + public const string InvalidAuthorityTypeTemplate = "This method overload is not supported by '{0}'"; + public const string InvalidCredentialType = "Invalid credential type"; + public const string InvalidFormatParameterTemplate = "Parameter '{0}' has invalid format"; + public const string InvalidTokenCacheKeyFormat = "Invalid token cache key format"; + public const string MissingAuthenticateHeader = "WWW-Authenticate header was expected in the response"; + + public const string MultipleTokensMatched = + "The cache contains multiple tokens satisfying the requirements. Call AcquireToken again providing more requirements like authority"; + + public const string NetworkNotAvailable = "The network is down so authentication cannot proceed"; + public const string NoDataFromSTS = "No data received from security token service"; + public const string NullParameterTemplate = "Parameter '{0}' cannot be null"; + public const string ParsingMetadataDocumentFailed = "Parsing WS metadata exchange failed"; + public const string ParsingWsTrustResponseFailed = "Parsing WS-Trust response failed"; + public const string PasswordRequiredForManagedUserError = "Password is required for managed user"; + public const string RedirectUriContainsFragment = "'redirectUri' must NOT include a fragment component"; + public const string LoginHintNullForUiOption = "Null login_hint is not allowed for UIBehavior.ActAsCurrentUser"; + public const string ServiceReturnedError = "Service returned error. Check InnerException for more details"; + + public const string BrokerReponseHashMismatch = + "Unencrypted broker response hash did not match the expected hash"; + + public const string StsMetadataRequestFailed = + "Metadata request to Access Control service failed. Check InnerException for more details"; + + public const string StsTokenRequestFailed = + "Token request to security token service failed. Check InnerException for more details"; + + public const string UnauthorizedHttpStatusCodeExpected = + "Unauthorized Http Status Code (401) was expected in the response"; + + public const string UnauthorizedResponseExpected = "Unauthorized http response (status code 401) was expected"; + public const string UnexpectedAuthorityValidList = "Unexpected list of valid addresses"; + public const string Unknown = "Unknown error"; + public const string UnknownUser = "Could not identify logged in user"; + public const string UnsupportedUserType = "Unsupported User Type"; + + public const string UnsupportedAuthorityValidation = + "Authority validation is not supported for this type of authority"; + + public const string UnsupportedMultiRefreshToken = + "This authority does not support refresh token for multiple resources. Pass null as a resource"; + + public const string AuthenticationCanceled = "User canceled authentication"; + public const string UserMismatch = "User '{0}' returned by service does not match user '{1}' in the request"; + public const string UserCredentialAssertionTypeEmpty = "credential.AssertionType cannot be empty"; + + public const string NoPromptFailedErrorMessage = + "One of two conditions was encountered: " + + + "1. The UiBehavior.Never flag was passed, but the constraint could not be honored, because user interaction was required. " + + + "2. An error occurred during a silent web authentication that prevented the http authentication flow from completing in a short enough time frame"; + + public const string UserRealmDiscoveryFailed = "User realm discovery failed"; + + public const string WsTrustEndpointNotFoundInMetadataDocument = + "WS-Trust endpoint not found in metadata document"; + + public const string GetUserNameFailed = "Failed to get user name"; + + public const string MissingFederationMetadataUrl = + "Federation Metadata Url is missing for federated user. This user type is unsupported."; + + public const string SpecifyAnyUser = + "If you do not need access token for any specific user, pass userId=UserIdentifier.AnyUser instead of userId=null."; + + public const string IntegratedAuthFailed = + "Integrated authentication failed. You may try an alternative authentication method"; + + public const string DuplicateQueryParameterTemplate = "Duplicate query parameter '{0}' in extraQueryParameters"; + public const string DeviceCertificateNotFoundTemplate = "Device Certificate was not found for {0}"; + } + + internal class XmlNamespace + { + public static readonly XNamespace Wsdl = "http://schemas.xmlsoap.org/wsdl/"; + public static readonly XNamespace Wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy"; + public static readonly XNamespace Http = "http://schemas.microsoft.com/ws/06/2004/policy/http"; + public static readonly XNamespace Sp = "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"; + public static readonly XNamespace Sp2005 = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"; + + public static readonly XNamespace Wsu = + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; + + public static readonly XNamespace Soap12 = "http://schemas.xmlsoap.org/wsdl/soap12/"; + public static readonly XNamespace Wsa10 = "http://www.w3.org/2005/08/addressing"; + public static readonly XNamespace Trust = "http://docs.oasis-open.org/ws-sx/ws-trust/200512"; + public static readonly XNamespace Trust2005 = "http://schemas.xmlsoap.org/ws/2005/02/trust"; + public static readonly XNamespace Issue = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"; + public static readonly XNamespace Issue2005 = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue"; + public static readonly XNamespace SoapEnvelope = "http://www.w3.org/2003/05/soap-envelope"; + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta new file mode 100644 index 0000000..762f085 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3bd2e6e1ca085814daa6fd1dc5269a71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs new file mode 100644 index 0000000..d493d05 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs @@ -0,0 +1,73 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using System.Text; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class Extensions + { + internal static string GetPiiScrubbedDetails(this Exception ex) + { + string result = null; + if (ex != null) + { + var sb = new StringBuilder(); + + sb.Append(string.Format(CultureInfo.CurrentCulture, "Exception type: {0}", ex.GetType())); + + var msalException = ex as MsalException; + if (msalException != null) + { + sb.Append(string.Format(CultureInfo.CurrentCulture, ", ErrorCode: {0}", msalException.ErrorCode)); + } + + var msalServiceException = ex as MsalServiceException; + if (msalServiceException != null) + { + sb.Append(string.Format(CultureInfo.CurrentCulture, ", StatusCode: {0}", msalServiceException.StatusCode)); + } + + if (ex.InnerException != null) + { + sb.Append("---> " + GetPiiScrubbedDetails(ex.InnerException) + Environment.NewLine + "=== End of inner exception stack trace ==="); + } + + if (ex.StackTrace != null) + { + sb.Append(Environment.NewLine + ex.StackTrace); + } + + result = sb.ToString(); + } + + return result; + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta new file mode 100644 index 0000000..d8eb1d7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da4b5ea6f7e14c440be0cc0b12253ee7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta new file mode 100644 index 0000000..871a754 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e5d2324a9f903bf4f93f080b3c998121 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs new file mode 100644 index 0000000..3ded9b1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs @@ -0,0 +1,76 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Net.Http; + +namespace Microsoft.Identity.Client.Internal.Http +{ + internal class HttpClientFactory + { + // as per guidelines HttpClient should be a singeton instance in an application. + private static HttpClient _client; + private static readonly object LockObj = new object(); + public static bool ReturnHttpClientForMocks { set; get; } + public const long MaxResponseContentBufferSizeInBytes = 1024*1024; + + private static HttpClient CreateHttpClient() + { + var httpClient = new HttpClient(HttpMessageHandlerFactory.GetMessageHandler(ReturnHttpClientForMocks)) + { + MaxResponseContentBufferSize = MaxResponseContentBufferSizeInBytes + }; + + return httpClient; + } + + public static HttpClient GetHttpClient() + { + // we return a new instanceof httpclient beacause there + // is no way to provide new http request message handler + // for each request made and it makes mocking of network calls + // impossible. So to circumvent, we simply return new instance for + // for mocking purposes. + if (ReturnHttpClientForMocks) + { + return CreateHttpClient(); + } + + if (_client == null) + { + lock (LockObj) + { + if (_client == null) + { + _client = CreateHttpClient(); + } + } + } + + return _client; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta new file mode 100644 index 0000000..35614f9 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05fc9d2ee1cb7744baee182518e704c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs new file mode 100644 index 0000000..7dfc8f3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; +using System.Net.Http; + +namespace Microsoft.Identity.Client.Internal.Http +{ + internal static class HttpMessageHandlerFactory + { + private static readonly Queue MockHttpMessageHandlerQueue = new Queue(); + + internal static HttpMessageHandler GetMessageHandler(bool forMock) + { + return forMock ? MockHttpMessageHandlerQueue.Dequeue() : new HttpClientHandler(); + } + + internal static void AddMockHandler(HttpMessageHandler mockHandler) + { + MockHttpMessageHandlerQueue.Enqueue(mockHandler); + } + + internal static void ClearMockHandlers() + { + MockHttpMessageHandlerQueue.Clear(); + } + + internal static bool IsMocksQueueEmpty => MockHttpMessageHandlerQueue.Count == 0; + internal static int MockCount => MockHttpMessageHandlerQueue.Count; + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta new file mode 100644 index 0000000..d910f0a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57cc1b234be08c847b8d2ae9f838df4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs new file mode 100644 index 0000000..7a49ade --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs @@ -0,0 +1,180 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client.Internal.Http +{ + internal class HttpRequest + { + private HttpRequest() + { + } + + public static async Task SendPostAsync(Uri endpoint, Dictionary headers, + Dictionary bodyParameters, RequestContext requestContext) + { + return + await + ExecuteWithRetryAsync(endpoint, headers, bodyParameters, HttpMethod.Post, requestContext) + .ConfigureAwait(false); + } + + public static async Task SendGetAsync(Uri endpoint, Dictionary headers, + RequestContext requestContext) + { + return await ExecuteWithRetryAsync(endpoint, headers, null, HttpMethod.Get, requestContext).ConfigureAwait(false); + } + + private static HttpRequestMessage CreateRequestMessage(Uri endpoint, Dictionary headers) + { + HttpRequestMessage requestMessage = new HttpRequestMessage { RequestUri = endpoint }; + requestMessage.Headers.Accept.Clear(); + if (headers != null) + { + foreach (KeyValuePair kvp in headers) + { + requestMessage.Headers.Add(kvp.Key, kvp.Value); + } + } + + return requestMessage; + } + + private static async Task ExecuteWithRetryAsync(Uri endpoint, Dictionary headers, + Dictionary bodyParameters, HttpMethod method, + RequestContext requestContext, bool retry = true) + { + Exception toThrow = null; + bool isRetryable = false; + HttpResponse response = null; + try + { + response = await ExecuteAsync(endpoint, headers, bodyParameters, method).ConfigureAwait(false); + + if (response.StatusCode == HttpStatusCode.OK) + { + return response; + } + + var msg = string.Format(CultureInfo.InvariantCulture, + "Response status code does not indicate success: {0} ({1}).", + (int) response.StatusCode, response.StatusCode); + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + + if ((int)response.StatusCode >= 500 && (int)response.StatusCode < 600) + { + isRetryable = true; + } + } + catch (TaskCanceledException exception) + { + requestContext.Logger.Error(exception); + requestContext.Logger.ErrorPii(exception); + isRetryable = true; + toThrow = exception; + } + + if (isRetryable) + { + if (retry) + { + const string msg = "Retrying one more time.."; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); + return await ExecuteWithRetryAsync(endpoint, headers, bodyParameters, method, requestContext, false).ConfigureAwait(false); + } + + const string message = "Request retry failed."; + requestContext.Logger.Info(message); + requestContext.Logger.InfoPii(message); + if (toThrow != null) + { + throw new MsalServiceException(MsalServiceException.RequestTimeout, "Request to the endpoint timed out.", toThrow); + } + + throw new MsalServiceException(MsalServiceException.ServiceNotAvailable, + "Service is unavailable to process the request", (int) response.StatusCode); + } + + return response; + } + + private static async Task ExecuteAsync(Uri endpoint, Dictionary headers, + Dictionary bodyParameters, HttpMethod method) + { + HttpClient client = HttpClientFactory.GetHttpClient(); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + using (HttpRequestMessage requestMessage = CreateRequestMessage(endpoint, headers)) + { + requestMessage.Method = method; + if (bodyParameters != null) + { + requestMessage.Content = new FormUrlEncodedContent(bodyParameters); + } + + using (HttpResponseMessage responseMessage = + await client.SendAsync(requestMessage).ConfigureAwait(false)) + { + HttpResponse returnValue = await CreateResponseAsync(responseMessage).ConfigureAwait(false); + returnValue.UserAgent = client.DefaultRequestHeaders.UserAgent.ToString(); + return returnValue; + } + } + } + + private static async Task CreateResponseAsync(HttpResponseMessage response) + { + var headers = new Dictionary(); + if (response.Headers != null) + { + foreach (var kvp in response.Headers) + { + headers[kvp.Key] = kvp.Value.First(); + } + } + + return new HttpResponse + { + Headers = headers, + Body = await response.Content.ReadAsStringAsync().ConfigureAwait(false), + StatusCode = response.StatusCode + }; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta new file mode 100644 index 0000000..6393132 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2325359f719b7fb45907a8d14b37b2db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs new file mode 100644 index 0000000..4e80e91 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; +using System.Net; + +namespace Microsoft.Identity.Client.Internal.Http +{ + internal class HttpResponse + { + public Dictionary Headers { get; set; } + + public string Body { get; set; } + + public HttpStatusCode StatusCode { get; set; } + + public string UserAgent { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta new file mode 100644 index 0000000..6d5c581 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e4a8a0f2b597a648bbd72155b94a0bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs new file mode 100644 index 0000000..46217b9 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs @@ -0,0 +1,44 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client.Internal +{ + internal interface ILogger + { + void Error(string message); + + void Warning(string message); + + void Information(string message); + + void Verbose(string message); + + void Error(Exception ex); + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta new file mode 100644 index 0000000..115ec67 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4f2a2895d1eff14f931137a16391012 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs new file mode 100644 index 0000000..21da5d8 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs @@ -0,0 +1,112 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; + +namespace Microsoft.Identity.Client.Internal +{ + internal class IdTokenClaim + { + public const string Issuer = "iss"; + public const string ObjectId = "oid"; + public const string Subject = "sub"; + public const string TenantId = "tid"; + public const string Version = "ver"; + public const string PreferredUsername = "preferred_username"; + public const string Name = "name"; + public const string HomeObjectId = "home_oid"; + } + + [DataContract] + internal class IdToken + { + [DataMember(Name = IdTokenClaim.Issuer, IsRequired = false)] + public string Issuer { get; set; } + + [DataMember(Name = IdTokenClaim.ObjectId, IsRequired = false)] + public string ObjectId { get; set; } + + [DataMember(Name = IdTokenClaim.Subject, IsRequired = false)] + public string Subject { get; set; } + + [DataMember(Name = IdTokenClaim.TenantId, IsRequired = false)] + public string TenantId { get; set; } + + [DataMember(Name = IdTokenClaim.Version, IsRequired = false)] + public string Version { get; set; } + + [DataMember(Name = IdTokenClaim.PreferredUsername, IsRequired = false)] + public string PreferredUsername { get; set; } + + [DataMember(Name = IdTokenClaim.Name, IsRequired = false)] + public string Name { get; set; } + + [DataMember(Name = IdTokenClaim.HomeObjectId, IsRequired = false)] + public string HomeObjectId { get; set; } + + public static IdToken Parse(string idToken) + { + if (string.IsNullOrEmpty(idToken)) + { + return null; + } + + IdToken idTokenBody = null; + string[] idTokenSegments = idToken.Split(new[] {'.'}); + + if (idTokenSegments.Length < 2) + { + throw new MsalClientException(MsalClientException.InvalidJwtError, "ID Token must contain at least 2 parts."); + } + + try + { + byte[] idTokenBytes = Base64UrlHelpers.DecodeToBytes(idTokenSegments[1]); + using (var stream = new MemoryStream(idTokenBytes)) + { + var serializer = new DataContractJsonSerializer(typeof(IdToken)); + idTokenBody = (IdToken) serializer.ReadObject(stream); + } + } + catch (Exception exc) + { + throw new MsalClientException(MsalClientException.JsonParseError, + "Failed to parse the returned id token.", exc); + } + + return idTokenBody; + } + + public string GetUniqueId() + { + return ObjectId ?? Subject; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta new file mode 100644 index 0000000..b2fd8c7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9468d6f6518f2e4e8e07ec09e60bf11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta new file mode 100644 index 0000000..8435d34 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0758634a94e49dd4ea925e88e1383296 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs new file mode 100644 index 0000000..4f7cdc2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs @@ -0,0 +1,114 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class AadAuthority : Authority + { + private const string AadInstanceDiscoveryEndpoint = "https://login.microsoftonline.com/common/discovery/instance"; + private static readonly HashSet TrustedHostList = new HashSet() + { + "login.windows.net", // Microsoft Azure Worldwide + "login.chinacloudapi.cn", // Microsoft Azure China + "login.cloudgovapi.us", // Microsoft Azure US Government + "login.microsoftonline.us", // Microsoft Azure US Government + "login.microsoftonline.com", // Microsoft Azure Worldwide + "login.microsoftonline.de" // Microsoft Azure Blackforest + }; + + public AadAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) + { + AuthorityType = AuthorityType.Aad; + UpdateCanonicalAuthority(); + } + + protected void UpdateCanonicalAuthority() + { + UriBuilder uriBuilder = new UriBuilder(CanonicalAuthority); + if (uriBuilder.Host.Equals("login.windows.net", StringComparison.OrdinalIgnoreCase)) + { + uriBuilder.Host = "login.microsoftonline.com"; + } + + CanonicalAuthority = uriBuilder.Uri.AbsoluteUri; + } + + protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, + RequestContext requestContext) + { + + if (ValidateAuthority && !IsInTrustedHostList(new Uri(CanonicalAuthority).Host)) + { + OAuth2Client client = new OAuth2Client(); + client.AddQueryParameter("api-version", "1.0"); + client.AddQueryParameter("authorization_endpoint", CanonicalAuthority + "oauth2/v2.0/authorize"); + + InstanceDiscoveryResponse discoveryResponse = + await + client.DiscoverAadInstanceAsync(new Uri(AadInstanceDiscoveryEndpoint), requestContext) + .ConfigureAwait(false); + if (discoveryResponse.TenantDiscoveryEndpoint == null) + { + throw new MsalServiceException(discoveryResponse.Error, discoveryResponse.ErrorDescription); + } + + return discoveryResponse.TenantDiscoveryEndpoint; + } + + return GetDefaultOpenIdConfigurationEndpoint(); + } + + protected override bool ExistsInValidatedAuthorityCache(string userPrincipalName) + { + return ValidatedAuthorities.ContainsKey(CanonicalAuthority); + } + + protected override void AddToValidatedAuthorities(string userPrincipalName) + { + // add to the list of validated authorities so that we don't do openid configuration call + ValidatedAuthorities[CanonicalAuthority] = this; + } + + protected override string GetDefaultOpenIdConfigurationEndpoint() + { + return CanonicalAuthority + "v2.0/.well-known/openid-configuration"; + } + + internal static bool IsInTrustedHostList(string host) + { + return + !string.IsNullOrEmpty( + TrustedHostList.FirstOrDefault(a => string.Compare(host, a, StringComparison.OrdinalIgnoreCase) == 0)); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta new file mode 100644 index 0000000..28f7bfe --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97fabd328f5fca042b9f9a4a63108a2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs new file mode 100644 index 0000000..a115cd2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs @@ -0,0 +1,162 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted free of charge to any person obtaining a copy +// of this software and associated documentation files(the "Software") to deal +// in the Software without restriction including without limitation the rights +// to use copy modify merge publish distribute sublicense and / or sell +// copies of the Software and to permit persons to whom the Software is +// furnished to do so subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR +// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER +// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.Http; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class AdfsAuthority : Authority + { + private const string DefaultRealm = "http://schemas.microsoft.com/rel/trusted-realm"; + private readonly HashSet _validForDomainsList = new HashSet(); + public AdfsAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) + { + AuthorityType = AuthorityType.Adfs; + } + + protected override bool ExistsInValidatedAuthorityCache(string userPrincipalName) + { + if (string.IsNullOrEmpty(userPrincipalName)) + { + throw new MsalException("UPN is required for ADFS authority validation."); + } + + return ValidatedAuthorities.ContainsKey(CanonicalAuthority) && + ((AdfsAuthority) ValidatedAuthorities[CanonicalAuthority])._validForDomainsList.Contains( + GetDomainFromUpn(userPrincipalName)); + } + + protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext) + { + if (ValidateAuthority) + { + DrsMetadataResponse drsResponse = await GetMetadataFromEnrollmentServerAsync(userPrincipalName, requestContext).ConfigureAwait(false); + if (!string.IsNullOrEmpty(drsResponse.Error)) + { + throw new MsalServiceException(drsResponse.Error, drsResponse.ErrorDescription); + } + + if (drsResponse.IdentityProviderService?.PassiveAuthEndpoint == null) + { + throw new MsalServiceException("missing_passive_auth_endpoint", "missing_passive_auth_endpoint"); + } + + string resource = string.Format(CultureInfo.InvariantCulture, CanonicalAuthority); + string webfingerUrl = string.Format(CultureInfo.InvariantCulture, + "https://{0}/adfs/.well-known/webfinger?rel={1}&resource={2}", + drsResponse.IdentityProviderService.PassiveAuthEndpoint.Host, + DefaultRealm, resource); + + HttpResponse httpResponse = + await HttpRequest.SendGetAsync(new Uri(webfingerUrl), null, requestContext).ConfigureAwait(false); + + if (httpResponse.StatusCode != HttpStatusCode.OK) + { + throw new MsalServiceException("invalid_authority", "authority validation failed."); + } + + AdfsWebFingerResponse wfr = OAuth2Client.CreateResponse(httpResponse, requestContext, + false); + if ( + wfr.Links.FirstOrDefault( + a => + (a.Rel.Equals(DefaultRealm, StringComparison.OrdinalIgnoreCase) && + a.Href.Equals(resource, StringComparison.OrdinalIgnoreCase))) == null) + { + throw new MsalException("invalid_authority"); + } + } + + return GetDefaultOpenIdConfigurationEndpoint(); + } + + protected override string GetDefaultOpenIdConfigurationEndpoint() + { + return CanonicalAuthority + ".well-known/openid-configuration"; + } + + protected override void AddToValidatedAuthorities(string userPrincipalName) + { + AdfsAuthority authorityInstance = this; + if (ValidatedAuthorities.ContainsKey(CanonicalAuthority)) + { + authorityInstance = (AdfsAuthority) ValidatedAuthorities[CanonicalAuthority]; + } + + authorityInstance._validForDomainsList.Add(GetDomainFromUpn(userPrincipalName)); + ValidatedAuthorities[CanonicalAuthority] = authorityInstance; + } + + private async Task GetMetadataFromEnrollmentServerAsync(string userPrincipalName, + RequestContext requestContext) + { + try + { + //attempt to connect to on-premise enrollment server first. + return await QueryEnrollmentServerEndpointAsync(string.Format(CultureInfo.InvariantCulture, + "https://enterpriseregistration.{0}/enrollmentserver/contract", + GetDomainFromUpn(userPrincipalName)), requestContext).ConfigureAwait(false); + } + catch (Exception exc) + { + const string msg = "On-Premise ADFS enrollment server endpoint lookup failed. Error - "; + string noPiiMsg = exc.GetPiiScrubbedDetails(); + requestContext.Logger.Info(msg + noPiiMsg); + requestContext.Logger.InfoPii(msg + exc); + } + + return await QueryEnrollmentServerEndpointAsync(string.Format(CultureInfo.InvariantCulture, + "https://enterpriseregistration.windows.net/{0}/enrollmentserver/contract", + GetDomainFromUpn(userPrincipalName)), requestContext).ConfigureAwait(false); + } + + private async Task QueryEnrollmentServerEndpointAsync(string endpoint, RequestContext requestContext) + { + OAuth2Client client = new OAuth2Client(); + client.AddQueryParameter("api-version", "1.0"); + return await client.ExecuteRequestAsync(new Uri(endpoint), HttpMethod.Get, requestContext).ConfigureAwait(false); + } + + private string GetDomainFromUpn(string upn) + { + if (!upn.Contains("@")) + { + throw new ArgumentException("userPrincipalName does not contain @ character."); + } + + return upn.Split('@')[1]; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta new file mode 100644 index 0000000..fb3feb5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d2829a6bb815554ca85e6f54a4ee0ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs new file mode 100644 index 0000000..2d3ddc1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs @@ -0,0 +1,61 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted free of charge to any person obtaining a copy +// of this software and associated documentation files(the "Software") to deal +// in the Software without restriction including without limitation the rights +// to use copy modify merge publish distribute sublicense and / or sell +// copies of the Software and to permit persons to whom the Software is +// furnished to do so subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR +// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER +// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class AdfsWebFingerResponseClaim : OAuth2ResponseBaseClaim + { + public const string Subject = "subject"; + public const string Links = "links"; + public const string Rel = "rel"; + public const string Href = "href"; + } + + [DataContract(Name = AdfsWebFingerResponseClaim.Links)] + internal class LinksList + { + [DataMember(Name = AdfsWebFingerResponseClaim.Rel, IsRequired = false)] + public string Rel { get; set; } + + [DataMember(Name = AdfsWebFingerResponseClaim.Href, IsRequired = false)] + public string Href { get; set; } + } + + [DataContract] + internal class AdfsWebFingerResponse : OAuth2ResponseBase + { + [DataMember(Name = AdfsWebFingerResponseClaim.Subject, IsRequired = false)] + public string Subject { get; set; } + + [DataMember(Name = AdfsWebFingerResponseClaim.Links, IsRequired = false)] + public List Links { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta new file mode 100644 index 0000000..8153583 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a14f36ec8baa0484cb0855b8885b455c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs new file mode 100644 index 0000000..21126be --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs @@ -0,0 +1,259 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal enum AuthorityType + { + Aad, + Adfs, + B2C + } + + internal abstract class Authority + { + private static readonly HashSet TenantlessTenantNames = + new HashSet(new[] {"common", "organizations"}); + private bool _resolved; + + internal static readonly ConcurrentDictionary ValidatedAuthorities = + new ConcurrentDictionary(); + + private static readonly string RequiredAuthorityUriScheme = "https"; + + protected abstract Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext); + + public static Authority CreateAuthority(string authority, bool validateAuthority) + { + return CreateInstance(authority, validateAuthority); + } + + protected Authority(string authority, bool validateAuthority) + { + UriBuilder authorityUri = new UriBuilder(authority); + Host = authorityUri.Host; + string[] pathSegments = authorityUri.Uri.AbsolutePath.Substring(1).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + + CanonicalAuthority = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", authorityUri.Uri.Authority, + pathSegments[0]); + ValidateAuthority = validateAuthority; + } + + public AuthorityType AuthorityType { get; set; } + + public string CanonicalAuthority { get; set; } + + public bool ValidateAuthority { get; set; } + + public bool IsTenantless { get; set; } + + public string AuthorizationEndpoint { get; set; } + + public string TokenEndpoint { get; set; } + + public string EndSessionEndpoint { get; set; } + + public string SelfSignedJwtAudience { get; set; } + + public string Host { get; set; } + + public static void ValidateAsUri(string authority) + { + if (string.IsNullOrWhiteSpace(authority)) + { + throw new ArgumentNullException(nameof(authority)); + } + + if (!Uri.IsWellFormedUriString(authority, UriKind.Absolute)) + { + throw new ArgumentException(MsalErrorMessage.AuthorityInvalidUriFormat, nameof(authority)); + } + + var authorityUri = new Uri(authority); + if (authorityUri.Scheme != Authority.RequiredAuthorityUriScheme) + { + throw new ArgumentException(MsalErrorMessage.AuthorityUriInsecure, nameof(authority)); + } + + string path = authorityUri.AbsolutePath.Substring(1); + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(MsalErrorMessage.AuthorityUriInvalidPath, nameof(authority)); + } + + string[] pathSegments = authorityUri.AbsolutePath.Substring(1).Split('/'); + if (pathSegments == null || pathSegments.Length == 0) + { + throw new ArgumentException(MsalErrorMessage.AuthorityUriInvalidPath); + } + } + + private static Authority CreateInstance(string authority, bool validateAuthority) + { + authority = CanonicalizeUri(authority); + ValidateAsUri(authority); + string[] pathSegments = new Uri(authority).AbsolutePath.Substring(1).Split('/'); + bool isAdfsAuthority = string.Compare(pathSegments[0], "adfs", StringComparison.OrdinalIgnoreCase) == 0; + bool isB2CAuthority = string.Compare(pathSegments[0], B2CAuthority.Prefix, StringComparison.OrdinalIgnoreCase) == 0; + + if (isAdfsAuthority) + { + throw new MsalException(MsalError.InvalidAuthorityType, "ADFS is not a supported authority"); + } + + if (isB2CAuthority) + { + return new B2CAuthority(authority, validateAuthority); + } + + return new AadAuthority(authority, validateAuthority); + } + + public async Task ResolveEndpointsAsync(string userPrincipalName, RequestContext requestContext) + { + var msg = "Resolving authority endpoints... Already resolved? - " + _resolved; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + + if (!_resolved) + { + var authorityUri = new Uri(CanonicalAuthority); + string host = authorityUri.Authority; + string path = authorityUri.AbsolutePath.Substring(1); + string tenant = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal)); + IsTenantless = TenantlessTenantNames.Contains(tenant.ToLowerInvariant()); + // create log message + msg = "Is Authority tenantless? - " + IsTenantless; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + + if (ExistsInValidatedAuthorityCache(userPrincipalName)) + { + msg = "Authority found in validated authority cache"; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + Authority authority = ValidatedAuthorities[CanonicalAuthority]; + AuthorityType = authority.AuthorityType; + CanonicalAuthority = authority.CanonicalAuthority; + ValidateAuthority = authority.ValidateAuthority; + IsTenantless = authority.IsTenantless; + AuthorizationEndpoint = authority.AuthorizationEndpoint; + TokenEndpoint = authority.TokenEndpoint; + EndSessionEndpoint = authority.EndSessionEndpoint; + SelfSignedJwtAudience = authority.SelfSignedJwtAudience; + + return; + } + + string openIdConfigurationEndpoint = + await + GetOpenIdConfigurationEndpointAsync(userPrincipalName, requestContext) + .ConfigureAwait(false); + + //discover endpoints via openid-configuration + TenantDiscoveryResponse edr = + await DiscoverEndpointsAsync(openIdConfigurationEndpoint, requestContext).ConfigureAwait(false); + + if (string.IsNullOrEmpty(edr.AuthorizationEndpoint)) + { + throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, + "Authorize endpoint was not found in the openid configuration"); + } + + if (string.IsNullOrEmpty(edr.TokenEndpoint)) + { + throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, + "Token endpoint was not found in the openid configuration"); + } + + if (string.IsNullOrEmpty(edr.Issuer)) + { + throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, + "Issuer was not found in the openid configuration"); + } + + AuthorizationEndpoint = edr.AuthorizationEndpoint.Replace("{tenant}", tenant); + TokenEndpoint = edr.TokenEndpoint.Replace("{tenant}", tenant); + SelfSignedJwtAudience = edr.Issuer.Replace("{tenant}", tenant); + + _resolved = true; + + AddToValidatedAuthorities(userPrincipalName); + } + } + + protected abstract bool ExistsInValidatedAuthorityCache(string userPrincipalName); + + protected abstract void AddToValidatedAuthorities(string userPrincipalName); + + protected abstract string GetDefaultOpenIdConfigurationEndpoint(); + + private async Task DiscoverEndpointsAsync(string openIdConfigurationEndpoint, + RequestContext requestContext) + { + OAuth2Client client = new OAuth2Client(); + return + await + client.ExecuteRequestAsync(new Uri(openIdConfigurationEndpoint), + HttpMethod.Get, requestContext).ConfigureAwait(false); + } + + public static string UpdateTenantId(string authority, string replacementTenantId) + { + Uri authUri = new Uri(authority); + string[] pathSegments = authUri.AbsolutePath.Substring(1).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + + if (TenantlessTenantNames.Contains(pathSegments[0]) && !string.IsNullOrWhiteSpace(replacementTenantId)) + { + return string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", authUri.Authority, + replacementTenantId); + } + + return authority; + } + + public static string CanonicalizeUri(string uri) + { + if (!string.IsNullOrWhiteSpace(uri) && !uri.EndsWith("/", StringComparison.OrdinalIgnoreCase)) + { + uri = uri + "/"; + } + + return uri.ToLowerInvariant(); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta new file mode 100644 index 0000000..e148118 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5108c560a1062e64fb75bbd32a3a5b78 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs new file mode 100644 index 0000000..882831c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted free of charge to any person obtaining a copy +// of this software and associated documentation files(the "Software") to deal +// in the Software without restriction including without limitation the rights +// to use copy modify merge publish distribute sublicense and / or sell +// copies of the Software and to permit persons to whom the Software is +// furnished to do so subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR +// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER +// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using System.Threading.Tasks; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class B2CAuthority : AadAuthority + { + public const string Prefix = "tfp"; // The http path of B2C authority looks like "/tfp//..." + + public B2CAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) + { + Uri authorityUri = new Uri(authority); + string[] pathSegments = authorityUri.AbsolutePath.Substring(1).Split(new [] { '/'}, StringSplitOptions.RemoveEmptyEntries); + if (pathSegments.Length < 3) + { + throw new ArgumentException(MsalErrorMessage.B2cAuthorityUriInvalidPath); + } + + CanonicalAuthority = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/{2}/{3}/", authorityUri.Authority, + pathSegments[0], pathSegments[1], pathSegments[2]); + AuthorityType = AuthorityType.B2C; + UpdateCanonicalAuthority(); + } + + protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext) + { + if (ValidateAuthority && !IsInTrustedHostList(new Uri(CanonicalAuthority).Host)) + { + throw new ArgumentException(MsalErrorMessage.UnsupportedAuthorityValidation); + } + + return await Task.Run(() => GetDefaultOpenIdConfigurationEndpoint()).ConfigureAwait(false); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta new file mode 100644 index 0000000..538f738 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f6fe656f52b52344998412c59e44f3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs new file mode 100644 index 0000000..6cb78c0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs @@ -0,0 +1,53 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted free of charge to any person obtaining a copy +// of this software and associated documentation files(the "Software") to deal +// in the Software without restriction including without limitation the rights +// to use copy modify merge publish distribute sublicense and / or sell +// copies of the Software and to permit persons to whom the Software is +// furnished to do so subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR +// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER +// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class DrsMetadataResponseClaim : OAuth2ResponseBaseClaim + { + public const string PassiveAuthEndpoint = "PassiveAuthEndpoint"; + public const string IdentityProviderService = "IdentityProviderService"; + } + + [DataContract] + internal class IdentityProviderService + { + [DataMember(Name = DrsMetadataResponseClaim.PassiveAuthEndpoint, IsRequired = false)] + public Uri PassiveAuthEndpoint { get; set; } + } + + [DataContract] + internal class DrsMetadataResponse : OAuth2ResponseBase + { + [DataMember(Name = DrsMetadataResponseClaim.IdentityProviderService, IsRequired = false)] + public IdentityProviderService IdentityProviderService { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta new file mode 100644 index 0000000..9deceb1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 000543523d525a74fa324d826d6ba849 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs new file mode 100644 index 0000000..ceca1ab --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs @@ -0,0 +1,39 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted free of charge to any person obtaining a copy +// of this software and associated documentation files(the "Software") to deal +// in the Software without restriction including without limitation the rights +// to use copy modify merge publish distribute sublicense and / or sell +// copies of the Software and to permit persons to whom the Software is +// furnished to do so subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR +// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER +// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + [DataContract] + internal sealed class InstanceDiscoveryResponse : OAuth2ResponseBase + { + [DataMember(Name = "tenant_discovery_endpoint", IsRequired = false)] + public string TenantDiscoveryEndpoint { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta new file mode 100644 index 0000000..57d322e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 246b00acac8019048b665d5c85c1398d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs new file mode 100644 index 0000000..66e5a46 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Runtime.Serialization; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Instance +{ + internal class TenantDiscoveryResponseClaim : OAuth2ResponseBaseClaim + { + public const string AuthorizationEndpoint = "authorization_endpoint"; + public const string TokenEndpoint = "token_endpoint"; + public const string Issuer = "issuer"; + } + + [DataContract] + internal class TenantDiscoveryResponse : OAuth2ResponseBase + { + [DataMember(Name = TenantDiscoveryResponseClaim.AuthorizationEndpoint, IsRequired = false)] + public string AuthorizationEndpoint { get; set; } + + [DataMember(Name = TenantDiscoveryResponseClaim.TokenEndpoint, IsRequired = false)] + public string TokenEndpoint { get; set; } + + [DataMember(Name = TenantDiscoveryResponseClaim.Issuer, IsRequired = false)] + public string Issuer { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta new file mode 100644 index 0000000..89eab0a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac3dcddedd169de4fa94502ec91dfec0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta new file mode 100644 index 0000000..44ef001 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 70250363cbac48f4c93edf73cbac75c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs new file mode 100644 index 0000000..278ce1e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs @@ -0,0 +1,41 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client.Internal.Interfaces +{ + internal interface IWebUI + { + RequestContext RequestContext { get; set; } + + Task AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext); + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta new file mode 100644 index 0000000..6121991 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e687b74e9071fcd49af34347772c3f65 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs new file mode 100644 index 0000000..1aa1067 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Identity.Client.Internal.Interfaces +{ + internal interface IWebUIFactory + { + IWebUI CreateAuthenticationDialog(UIParent parent, RequestContext requestContext); + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta new file mode 100644 index 0000000..7cfaf0c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f026f8960a58eca4a8057a7269371f79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs new file mode 100644 index 0000000..af48155 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs @@ -0,0 +1,73 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.IO; +using System.Runtime.Serialization.Json; +using System.Text; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class JsonHelper + { + internal static string SerializeToJson(T toEncode) + { + using (MemoryStream stream = new MemoryStream()) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof (T)); + ser.WriteObject(stream, toEncode); + return Encoding.UTF8.GetString(stream.ToArray(), 0, (int) stream.Position); + } + } + + internal static T DeserializeFromJson(string json) + { + if (string.IsNullOrEmpty(json)) + { + return default(T); + } + + return DeserializeFromJson(json.ToByteArray()); + } + + internal static T DeserializeFromJson(byte[] jsonByteArray) + { + if (jsonByteArray == null || jsonByteArray.Length == 0) + { + return default(T); + } + + T response; + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (T)); + using (MemoryStream stream = new MemoryStream(jsonByteArray)) + { + response = ((T) serializer.ReadObject(stream)); + } + + return response; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta new file mode 100644 index 0000000..6c4b793 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d47cbe545f070c44b7cd993621425e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs new file mode 100644 index 0000000..1b61613 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Identity.Client.Internal +{ + /// + /// Error code returned as a property in MsalException + /// + internal static class MsalError + { + /// + /// Authentication failed. + /// + public const string AuthenticationFailed = "authentication_failed"; + + + /// + /// Authority validation failed. + /// + public const string AuthorityValidationFailed = "authority_validation_failed"; + + /// + /// Invalid owner window type. + /// + public const string InvalidOwnerWindowType = "invalid_owner_window_type"; + + /// + /// Invalid authority type. + /// + public const string InvalidAuthorityType = "invalid_authority_type"; + + /// + /// Invalid service URL. + /// + public const string InvalidServiceUrl = "invalid_service_url"; + + /// + /// Encoded token too long. + /// + public const string EncodedTokenTooLong = "encoded_token_too_long"; + + /// + /// No data from STS. + /// + public const string NoDataFromSts = "no_data_from_sts"; + + /// + /// User Mismatch. + /// + public const string UserMismatch = "user_mismatch"; + + /// + /// Failed to refresh token. + /// + public const string FailedToRefreshToken = "failed_to_refresh_token"; + + /// + /// RedirectUri validation failed. + /// + public const string RedirectUriValidationFailed = "redirect_uri_validation_failed"; + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta new file mode 100644 index 0000000..63d388c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2cbe2fa1b8d281a4a8e47384b8922042 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs new file mode 100644 index 0000000..e7f104e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs @@ -0,0 +1,378 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class MsalHelpers + { + public static string ToStringInvariant(this int val) + { + return val.ToString(CultureInfo.InvariantCulture); + } + + public static string ToStringInvariant(this long val) + { + return val.ToString(CultureInfo.InvariantCulture); + } + + public static bool ScopeContains(this SortedSet scopes, SortedSet otherScope) + { + foreach (string otherString in otherScope) + { + if (!scopes.Contains(otherString, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + + return true; + } + + public static bool ScopeIntersects(this SortedSet scopes, SortedSet otherScope) + { + return scopes.Overlaps(otherScope); + } + + internal static string[] AsArray(this SortedSet setOfStrings) + { + return setOfStrings?.ToArray(); + } + + internal static string AsSingleString(this IEnumerable input) + { + if (IsNullOrEmpty(input)) + { + return string.Empty; + } + + return string.Join(" ", input); + } + + internal static SortedSet AsSet(this string singleString) + { + if (string.IsNullOrEmpty(singleString)) + { + return new SortedSet(); + } + + return new SortedSet(singleString.Split(new[] { " " }, StringSplitOptions.None)); + } + + internal static string[] AsArray(this string singleString) + { + if (string.IsNullOrWhiteSpace(singleString)) + { + return new string[] { }; + } + + return singleString.Split(new[] { " " }, StringSplitOptions.None); + } + + internal static SortedSet CreateSetFromEnumerable(this IEnumerable input) + { + if (input == null || !input.Any()) + { + return new SortedSet(); + } + return new SortedSet(input); + } + + internal static bool IsNullOrEmpty(IEnumerable input) + { + return input == null || !input.Any(); + } + + internal static string ByteArrayToString(byte[] input) + { + if (input == null || input.Length == 0) + { + return null; + } + + return Encoding.UTF8.GetString(input, 0, input.Length); + } + + public static DateTime UnixTimestampToDateTime(double unixTimestamp) + { + DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + dateTime = dateTime.AddSeconds(unixTimestamp).ToUniversalTime(); + return dateTime; + } + + public static long DateTimeToUnixTimestamp(DateTimeOffset dateTimeOffset) + { + DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + long unixTimestamp = (long)dateTimeOffset.Subtract(dateTime).TotalSeconds; + return unixTimestamp; + } + + public static long DateTimeToUnixTimestampMilliseconds(DateTimeOffset dateTimeOffset) + { + DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + long unixTimestamp = (long)dateTimeOffset.Subtract(dateTime).TotalMilliseconds; + return unixTimestamp; + } + + public static string CreateString(byte[] bytes) + { + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } + + public static string UrlEncode(string message) + { + if (string.IsNullOrEmpty(message)) + { + return message; + } + + message = Uri.EscapeDataString(message); + message = message.Replace("%20", "+"); + + return message; + } + + public static string UrlDecode(string message) + { + if (string.IsNullOrEmpty(message)) + { + return message; + } + + message = message.Replace("+", "%20"); + message = Uri.UnescapeDataString(message); + + return message; + } + + public static void AddKeyValueString(StringBuilder messageBuilder, string key, string value) + { + AddKeyValueString(messageBuilder, key, value.ToCharArray()); + } + + public static string ToQueryParameter(this IDictionary input) + { + StringBuilder builder = new StringBuilder(); + + if (input.Count > 0) + { + foreach (var key in input.Keys) + { + builder.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", key, UrlEncode(input[key])); + } + + if (builder.Length > 0) + { + builder.Remove(builder.Length - 1, 1); + } + } + + return builder.ToString(); + } + + public static Dictionary ParseKeyValueList(string input, char delimiter, bool urlDecode, + bool lowercaseKeys, + RequestContext requestContext) + { + var response = new Dictionary(); + + List queryPairs = SplitWithQuotes(input, delimiter); + + foreach (string queryPair in queryPairs) + { + List pair = SplitWithQuotes(queryPair, '='); + + if (pair.Count == 2 && !string.IsNullOrWhiteSpace(pair[0]) && !string.IsNullOrWhiteSpace(pair[1])) + { + string key = pair[0]; + string value = pair[1]; + + // Url decoding is needed for parsing OAuth response, but not for parsing WWW-Authenticate header in 401 challenge + if (urlDecode) + { + key = UrlDecode(key); + value = UrlDecode(value); + } + + if (lowercaseKeys) + { + key = key.Trim().ToLowerInvariant(); + } + + value = value.Trim().Trim('\"').Trim(); + + if (response.ContainsKey(key)) + { + var msg = string.Format(CultureInfo.InvariantCulture, + "Key/value pair list contains redundant key '{0}'.", key); + requestContext?.Logger.Warning(msg); + requestContext?.Logger.WarningPii(msg); + } + + response[key] = value; + } + } + + return response; + } + + public static Dictionary ParseKeyValueList(string input, char delimiter, bool urlDecode, + RequestContext requestContext) + { + return ParseKeyValueList(input, delimiter, urlDecode, true, requestContext); + } + + public static byte[] ToByteArray(this String stringInput) + { + return ToByteArray(new StringBuilder(stringInput)); + } + + public static byte[] ToByteArray(this StringBuilder stringBuilder) + { + if (stringBuilder == null) + { + return null; + } + + UTF8Encoding encoding = new UTF8Encoding(); + var messageChars = new char[stringBuilder.Length]; + + try + { + stringBuilder.CopyTo(0, messageChars, 0, stringBuilder.Length); + return encoding.GetBytes(messageChars); + } + finally + { + messageChars.SecureClear(); + } + } + + public static void SecureClear(this StringBuilder stringBuilder) + { + if (stringBuilder != null) + { + for (int i = 0; i < stringBuilder.Length; i++) + { + stringBuilder[i] = '\0'; + } + + stringBuilder.Length = 0; + } + } + + public static void SecureClear(this byte[] bytes) + { + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = 0; + } + } + } + + public static void SecureClear(this char[] chars) + { + if (chars != null) + { + for (int i = 0; i < chars.Length; i++) + { + chars[i] = '\0'; + } + } + } + + internal static List SplitWithQuotes(string input, char delimiter) + { + List items = new List(); + + if (string.IsNullOrWhiteSpace(input)) + { + return items; + } + + int startIndex = 0; + bool insideString = false; + string item; + for (int i = 0; i < input.Length; i++) + { + if (input[i] == delimiter && !insideString) + { + item = input.Substring(startIndex, i - startIndex); + if (!string.IsNullOrWhiteSpace(item.Trim())) + { + items.Add(item); + } + + startIndex = i + 1; + } + else if (input[i] == '"') + { + insideString = !insideString; + } + } + + item = input.Substring(startIndex); + if (!string.IsNullOrWhiteSpace(item.Trim())) + { + items.Add(item); + } + + return items; + } + + public static void AppendQueryParameters(this UriBuilder builder, string queryParams) + { + if (builder == null || string.IsNullOrEmpty(queryParams)) + { + return; + } + + if (builder.Query.Length > 1) + { + builder.Query = builder.Query.Substring(1) + "&" + queryParams; + } + else + { + builder.Query = queryParams; + } + } + + private static void AddKeyValueString(StringBuilder messageBuilder, string key, char[] value) + { + string delimiter = (messageBuilder.Length == 0) ? string.Empty : "&"; + messageBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}=", delimiter, key); + messageBuilder.Append(value); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta new file mode 100644 index 0000000..72b53fc --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a27456c62b04b694989d038f39bc113e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs new file mode 100644 index 0000000..dee41b1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs @@ -0,0 +1,125 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class MsalIdParameter + { + /// + /// MSAL Flavor: .NET or WinRT + /// + public const string Product = "x-client-SKU"; + + /// + /// MSAL assembly version + /// + public const string Version = "x-client-Ver"; + + /// + /// CPU platform with x86, x64 or ARM as value + /// + public const string CpuPlatform = "x-client-CPU"; + + /// + /// Version of the operating system. This will not be sent on WinRT + /// + public const string OS = "x-client-OS"; + + /// + /// Device model. This will not be sent on .NET + /// + public const string DeviceModel = "x-client-DM"; + } + + /// + /// This class adds additional query parameters or headers to the requests sent to STS. This can help us in + /// collecting statistics and potentially on diagnostics. + /// + internal static class MsalIdHelper + { + private static readonly Regex MsalVersionRegex = new Regex(@"Version=[\d]+.[\d+]+.[\d]+.[\d]+", RegexOptions.CultureInvariant); + + public static IDictionary GetMsalIdParameters() + { + var parameters = new Dictionary(); + + parameters[MsalIdParameter.Product] = PlatformPlugin.PlatformInformation.GetProductName(); + parameters[MsalIdParameter.Version] = GetMsalVersion(); + + var processorInofrmation = PlatformPlugin.PlatformInformation.GetProcessorArchitecture(); + if (processorInofrmation != null) + { + parameters[MsalIdParameter.CpuPlatform] = processorInofrmation; + } + + var osInformation = PlatformPlugin.PlatformInformation.GetOperatingSystem(); + if (osInformation != null) + { + parameters[MsalIdParameter.OS] = osInformation; + } + + var deviceInformation = PlatformPlugin.PlatformInformation.GetDeviceModel(); + if (deviceInformation != null) + { + parameters[MsalIdParameter.DeviceModel] = deviceInformation; + } + + return parameters; + } + + public static string GetMsalVersion() + { + string fullVersion = typeof(MsalIdHelper).GetTypeInfo().Assembly.FullName; + + Match match = MsalVersionRegex.Match(fullVersion); + if (match.Success) + { + string[] version = match.Groups[0].Value.Split(new[] {'='}, StringSplitOptions.None); + return version[1]; + } + + return null; + } + + public static string GetAssemblyFileVersion() + { + return PlatformPlugin.PlatformInformation.GetAssemblyFileVersionAttribute(); + } + + public static string GetAssemblyInformationalVersion() + { + AssemblyInformationalVersionAttribute attribute = + typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute(); + return (attribute != null) ? attribute.InformationalVersion : string.Empty; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta new file mode 100644 index 0000000..1442f0e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bc29bf09a4a5404e917b495da71fb5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta new file mode 100644 index 0000000..ea84f60 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: be415a15ae5a8bd4895c37c49b806038 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs new file mode 100644 index 0000000..4778d83 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs @@ -0,0 +1,198 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.Http; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client.Internal.OAuth2 +{ + internal class OAuth2Client + { + private readonly Dictionary _bodyParameters = new Dictionary(); + + private readonly Dictionary _headers = + new Dictionary(MsalIdHelper.GetMsalIdParameters()); + + private readonly Dictionary _queryParameters = new Dictionary(); + + public void AddQueryParameter(string key, string value) + { + _queryParameters[key] = value; + } + + public void AddHeader(string key, string value) + { + _headers[key] = value; + } + + public void AddBodyParameter(string key, string value) + { + _bodyParameters[key] = value; + } + + public async Task GetOpenIdConfigurationAsync(Uri endPoint, RequestContext requestContext) + { + return await ExecuteRequestAsync(endPoint, HttpMethod.Get, requestContext).ConfigureAwait(false); + } + + public async Task DiscoverAadInstanceAsync(Uri endPoint, RequestContext requestContext) + { + return await ExecuteRequestAsync(endPoint, HttpMethod.Get, requestContext).ConfigureAwait(false); + } + + public async Task GetTokenAsync(Uri endPoint, RequestContext requestContext) + { + return await ExecuteRequestAsync(endPoint, HttpMethod.Post, requestContext).ConfigureAwait(false); + } + + internal async Task ExecuteRequestAsync(Uri endPoint, HttpMethod method, RequestContext requestContext) + { + bool addCorrelationId = (requestContext != null && !string.IsNullOrEmpty(requestContext.CorrelationId)); + if (addCorrelationId) + { + _headers.Add(OAuth2Header.CorrelationId, requestContext.CorrelationId); + _headers.Add(OAuth2Header.RequestCorrelationIdInResponse, "true"); + } + + HttpResponse response = null; + Uri endpointUri = CreateFullEndpointUri(endPoint); + var httpEvent = new HttpEvent(){HttpPath = endpointUri, QueryParams = endpointUri.Query}; + Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, httpEvent); + try + { + if (method == HttpMethod.Post) + { + response = await HttpRequest.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext).ConfigureAwait(false); + } + else + { + response = await HttpRequest.SendGetAsync(endpointUri, _headers, requestContext).ConfigureAwait(false); + } + + httpEvent.HttpResponseStatus = (int) response.StatusCode; + httpEvent.UserAgent = response.UserAgent; + if (response.StatusCode != HttpStatusCode.OK) + { + httpEvent.OauthErrorCode = JsonHelper.DeserializeFromJson(response.Body).Error; + } + } + finally + { + Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, httpEvent); + } + + return CreateResponse(response, requestContext, addCorrelationId); + } + + public static T CreateResponse(HttpResponse response, RequestContext requestContext, bool addCorrelationId) + { + if (response.StatusCode != HttpStatusCode.OK) + { + CreateErrorResponse(response, requestContext); + } + + if (addCorrelationId) + { + VerifyCorrelationIdHeaderInReponse(response.Headers, requestContext); + } + + return JsonHelper.DeserializeFromJson(response.Body); + } + + public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext) + { + MsalServiceException serviceEx; + try + { + TokenResponse tokenResponse = JsonHelper.DeserializeFromJson(response.Body); + + if (MsalUiRequiredException.InvalidGrantError.Equals(tokenResponse.Error, + StringComparison.OrdinalIgnoreCase)) + { + throw new MsalUiRequiredException(MsalUiRequiredException.InvalidGrantError, + tokenResponse.ErrorDescription) + { + Claims = tokenResponse.Claims + }; + } + + serviceEx = new MsalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, (int)response.StatusCode, tokenResponse.Claims, null) + { + ResponseBody = response.Body + }; + } + catch (SerializationException) + { + serviceEx = new MsalServiceException(MsalException.UnknownError, response.Body, (int)response.StatusCode); + } + + requestContext.Logger.Error(serviceEx); + requestContext.Logger.ErrorPii(serviceEx); + throw serviceEx; + } + + internal Uri CreateFullEndpointUri(Uri endPoint) + { + UriBuilder endpointUri = new UriBuilder(endPoint); + string extraQp = _queryParameters.ToQueryParameter(); + endpointUri.AppendQueryParameters(extraQp); + + return endpointUri.Uri; + } + + private static void VerifyCorrelationIdHeaderInReponse(Dictionary headers, RequestContext requestContext) + { + foreach (string reponseHeaderKey in headers.Keys) + { + string trimmedKey = reponseHeaderKey.Trim(); + if (string.Compare(trimmedKey, OAuth2Header.CorrelationId, StringComparison.OrdinalIgnoreCase) == 0) + { + string correlationIdHeader = headers[trimmedKey].Trim(); + if (!string.Equals(correlationIdHeader, requestContext.CorrelationId)) + { + requestContext.Logger.Warning("Returned correlation id does not match the sent correlation id"); + requestContext.Logger.WarningPii(string.Format(CultureInfo.InvariantCulture, + "Returned correlation id '{0}' does not match the sent correlation id '{1}'", + correlationIdHeader, requestContext.CorrelationId)); + } + + break; + } + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta new file mode 100644 index 0000000..3b7465e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59e69fa498f9e6c4cb10f4a461c727a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs new file mode 100644 index 0000000..362ff60 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Runtime.Serialization; + +namespace Microsoft.Identity.Client.Internal.OAuth2 +{ + internal class OAuth2ResponseBaseClaim + { + public const string Claims = "claims"; + public const string Error = "error"; + public const string ErrorDescription = "error_description"; + public const string ErrorCodes = "error_codes"; + public const string CorrelationId = "correlation_id"; + } + + [DataContract] + internal class OAuth2ResponseBase + { + [DataMember(Name = OAuth2ResponseBaseClaim.Error, IsRequired = false)] + public string Error { get; set; } + + [DataMember(Name = OAuth2ResponseBaseClaim.ErrorDescription, IsRequired = false)] + public string ErrorDescription { get; set; } + + [DataMember(Name = OAuth2ResponseBaseClaim.ErrorCodes, IsRequired = false)] + public string[] ErrorCodes { get; set; } + + [DataMember(Name = OAuth2ResponseBaseClaim.CorrelationId, IsRequired = false)] + public string CorrelationId { get; set; } + + [DataMember(Name = OAuth2ResponseBaseClaim.Claims, IsRequired = false)] + public string Claims { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta new file mode 100644 index 0000000..a7a8521 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8e49c049980d8c41a833fc6b656bf7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs new file mode 100644 index 0000000..0e40e4f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs @@ -0,0 +1,114 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Identity.Client.Internal.OAuth2 +{ + internal class OAuth2Parameter + { + public const string ResponseType = "response_type"; + public const string GrantType = "grant_type"; + public const string ClientId = "client_id"; + public const string ClientSecret = "client_secret"; + public const string ClientAssertion = "client_assertion"; + public const string ClientAssertionType = "client_assertion_type"; + public const string RefreshToken = "refresh_token"; + public const string RedirectUri = "redirect_uri"; + public const string Resource = "resource"; + public const string Code = "code"; + public const string Scope = "scope"; + public const string Assertion = "assertion"; + public const string RequestedTokenUse = "requested_token_use"; + public const string Username = "username"; + public const string Password = "password"; + public const string LoginHint = "login_hint"; // login_hint is not standard oauth2 parameter + public const string CorrelationId = OAuth2Header.CorrelationId; + public const string State = "state"; + + public const string CodeChallengeMethod = "code_challenge_method"; + public const string CodeChallenge = "code_challenge"; + public const string CodeVerifier = "code_verifier"; + // correlation id is not standard oauth2 parameter + public const string LoginReq = "login_req"; + public const string DomainReq = "domain_req"; + + public const string Prompt = "prompt"; // prompt is not standard oauth2 parameter + public const string ClientInfo = "client_info"; // restrict_to_hint is not standard oauth2 parameter + } + + internal class OAuth2GrantType + { + public const string AuthorizationCode = "authorization_code"; + public const string RefreshToken = "refresh_token"; + public const string ClientCredentials = "client_credentials"; + public const string Saml11Bearer = "urn:ietf:params:oauth:grant-type:saml1_1-bearer"; + public const string Saml20Bearer = "urn:ietf:params:oauth:grant-type:saml2-bearer"; + public const string JwtBearer = "urn:ietf:params:oauth:grant-type:jwt-bearer"; + public const string Password = "password"; + public const string DeviceCode = "device_code"; + } + + internal class OAuth2ResponseType + { + public const string Code = "code"; + } + + internal class OAuth2AssertionType + { + public const string JwtBearer = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"; + } + + internal class OAuth2RequestedTokenUse + { + public const string OnBehalfOf = "on_behalf_of"; + } + + internal class OAuth2Header + { + public const string CorrelationId = "client-request-id"; + public const string RequestCorrelationIdInResponse = "return-client-request-id"; + } + + internal class OAuth2Error + { + public const string LoginRequired = "login_required"; + } + + internal class OAuth2Value + { + public static readonly string[] ReservedScopes = {"openid", "profile", "offline_access"}; + public const string CodeChallengeMethodValue = "S256"; + } + + internal class PromptValue + { + public const string Login = "login"; + public const string RefreshSession = "refresh_session"; + // The behavior of this value is identical to prompt=none for managed users; However, for federated users, AAD + // redirects to ADFS as it cannot determine in advance whether ADFS can login user silently (e.g. via WIA) or not. + public const string AttemptNone = "attempt_none"; + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta new file mode 100644 index 0000000..eb10838 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cfcdad38081e8e4daafbb36c5183131 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs new file mode 100644 index 0000000..b27f581 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.Identity.Client.Internal.OAuth2 +{ + internal class TokenResponseClaim : OAuth2ResponseBaseClaim + { + public const string Code = "code"; + public const string TokenType = "token_type"; + public const string AccessToken = "access_token"; + public const string RefreshToken = "refresh_token"; + public const string Scope = "scope"; + public const string ClientInfo = "client_info"; + public const string IdToken = "id_token"; + public const string ExpiresIn = "expires_in"; + } + + [DataContract] + internal class TokenResponse : OAuth2ResponseBase + { + [DataMember(Name = TokenResponseClaim.TokenType, IsRequired = false)] + public string TokenType { get; set; } + + [DataMember(Name = TokenResponseClaim.AccessToken, IsRequired = false)] + public string AccessToken { get; set; } + + [DataMember(Name = TokenResponseClaim.RefreshToken, IsRequired = false)] + public string RefreshToken { get; set; } + + [DataMember(Name = TokenResponseClaim.Scope, IsRequired = false)] + public string Scope { get; set; } + + [DataMember(Name = TokenResponseClaim.ClientInfo, IsRequired = false)] + public string ClientInfo { get; set; } + + [DataMember(Name = TokenResponseClaim.IdToken, IsRequired = false)] + public string IdToken { get; set; } + + [DataMember(Name = TokenResponseClaim.ExpiresIn, IsRequired = false)] + public long ExpiresIn { get; set; } + + public DateTimeOffset AccessTokenExpiresOn + { + get { return DateTime.UtcNow + TimeSpan.FromSeconds(ExpiresIn); } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta new file mode 100644 index 0000000..d80cf2d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ce97686a77e28e4bb7f8301304dcf1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs new file mode 100644 index 0000000..80918bf --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs @@ -0,0 +1,85 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal +{ + internal abstract class PlatformInformationBase + { + internal const string DefaultRedirectUri = "urn:ietf:wg:oauth:2.0:oob"; + + protected readonly RequestContext RequestContext; + protected PlatformInformationBase(RequestContext requestContext) + { + RequestContext = requestContext; + } + + public abstract string GetProductName(); + public abstract string GetEnvironmentVariable(string variable); + public abstract string GetProcessorArchitecture(); + public abstract string GetOperatingSystem(); + public abstract string GetDeviceModel(); + + public virtual string GetAssemblyFileVersionAttribute() + { + return + typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute().Version; + } + + public virtual async Task IsUserLocalAsync(RequestContext requestContext) + { + return await Task.Factory.StartNew(() => false).ConfigureAwait(false); + } + + public virtual bool IsDomainJoined() + { + return false; + } + + public virtual void ValidateRedirectUri(Uri redirectUri, RequestContext requestContext) + { + if (redirectUri == null) + { + throw new ArgumentNullException(nameof(redirectUri)); + } + } + + public virtual string GetRedirectUriAsString(Uri redirectUri, RequestContext requestContext) + { + return redirectUri.OriginalString; + } + + public virtual string GetDefaultRedirectUri(string correlationId) + { + return DefaultRedirectUri; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta new file mode 100644 index 0000000..71a8e20 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49988b45c72f4a549b5960af82a47f99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs new file mode 100644 index 0000000..69f6e74 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.Identity.Client.Internal.Interfaces; + +namespace Microsoft.Identity.Client.Internal +{ + internal static class PlatformPluginSwitch + { + static PlatformPluginSwitch() + { + DynamicallyLinkAssembly = true; + } + + public static bool DynamicallyLinkAssembly { get; set; } + } + + internal static class PlatformPlugin + { + private const string Namespace = "Microsoft.Identity.Client."; + + static PlatformPlugin() + { + if (PlatformPluginSwitch.DynamicallyLinkAssembly) + { + InitializeByAssemblyDynamicLinking(); + } + } + + public static IWebUIFactory WebUIFactory { get; set; } + + public static ILogger PlatformLogger { get; set; } + public static PlatformInformationBase PlatformInformation { get; set; } + + public static void InitializeByAssemblyDynamicLinking() + { +#if !FACADE + InjectDependecies( + (IWebUIFactory) new UI.WebUIFactory(), + (ILogger) new EventsSource.PlatformLogger(), + (PlatformInformationBase) new PlatformInformation(new RequestContext(Guid.Empty, null))); +#endif + } + + public static void InjectDependecies(IWebUIFactory webUIFactory, + ILogger platformlogger, + PlatformInformationBase platformInformation) + { + WebUIFactory = webUIFactory; + PlatformLogger = platformlogger; + PlatformInformation = platformInformation; + } + + public static void LogMessage(Logger.LogLevel logLevel, string formattedMessage) + { + switch (logLevel) + { + case Logger.LogLevel.Error: + PlatformLogger.Error(formattedMessage); + break; + case Logger.LogLevel.Warning: + PlatformLogger.Warning(formattedMessage); + break; + case Logger.LogLevel.Info: + PlatformLogger.Information(formattedMessage); + break; + case Logger.LogLevel.Verbose: + PlatformLogger.Verbose(formattedMessage); + break; + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta new file mode 100644 index 0000000..522ae31 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c23aa7ad787e79a49af035b59670c029 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs new file mode 100644 index 0000000..6bdccb6 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs @@ -0,0 +1,46 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client.Internal +{ + internal class RequestContext + { + public string CorrelationId { get; } + + public Logger Logger { get; set; } + + public string TelemetryRequestId { get; set; } + + public RequestContext(Guid correlationId, string component) + { + CorrelationId = correlationId.ToString(); + Logger = new Logger(correlationId, component); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta new file mode 100644 index 0000000..02fc0d5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b34633e3493394a4f965b6ef4edcf1d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta new file mode 100644 index 0000000..f2ee793 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3eccb36c6aa89174dbba4d918a91108c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs new file mode 100644 index 0000000..07fa2c8 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs @@ -0,0 +1,165 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class AuthenticationRequestParameters + { + public RequestContext RequestContext { get; set; } + + public Authority Authority { get; set; } + + public string TenantUpdatedCanonicalAuthority { get; set; } + + public bool ValidateAuthority { get; set; } + + public TokenCache TokenCache { get; set; } + + public SortedSet Scope { get; set; } + + public string ClientId { get; set; } + + public string AuthorizationCode { get; set; } + + public Uri RedirectUri { get; set; } + + public string LoginHint { get; set; } + + public string ExtraQueryParameters { get; set; } + + public IUser User { get; set; } + + public ClientInfo ClientInfo { get; set; } + + public UserAssertion UserAssertion { get; set; } + + public bool IsClientCredentialRequest { get; set; } = false; + public string SliceParameters { get; set; } + +#if DESKTOP || NETSTANDARD1_3 + public ClientCredential ClientCredential { get; set; } +#endif + + public IDictionary ToParameters() + { + IDictionary parameters = new Dictionary(); +#if DESKTOP || NETSTANDARD1_3 + if (ClientCredential != null) + { + if (!string.IsNullOrEmpty(ClientCredential.Secret)) + { + parameters[OAuth2Parameter.ClientSecret] = ClientCredential.Secret; + } + else + { + if (ClientCredential.Assertion == null || ClientCredential.ValidTo != 0) + { + bool assertionNearExpiry = (ClientCredential.ValidTo <= + Jwt.JsonWebToken.ConvertToTimeT(DateTime.UtcNow + + TimeSpan.FromMinutes( + Constants + .ExpirationMarginInMinutes))); + if (assertionNearExpiry) + { + const string msg = "Client Assertion does not exist or near expiry."; + RequestContext.Logger.Info(msg); + RequestContext.Logger.InfoPii(msg); + Jwt.JsonWebToken jwtToken = new Jwt.JsonWebToken(ClientId, + Authority.SelfSignedJwtAudience); + ClientCredential.Assertion = jwtToken.Sign(ClientCredential.Certificate); + ClientCredential.ValidTo = jwtToken.Payload.ValidTo; + } + else + { + const string msg = "Reusing the unexpired Client Assertion..."; + RequestContext.Logger.Info(msg); + RequestContext.Logger.InfoPii(msg); + } + } + + parameters[OAuth2Parameter.ClientAssertionType] = OAuth2AssertionType.JwtBearer; + parameters[OAuth2Parameter.ClientAssertion] = ClientCredential.Assertion; + } + } +#endif + return parameters; + } + + public void LogState() + { + // Create Pii enabled string builder + StringBuilder builder = new StringBuilder(Environment.NewLine + "=== Request Data ===" + Environment.NewLine + + "Authority Provided? - " + (Authority != null) + Environment.NewLine); + builder.AppendLine("Client Id - " + ClientId); + builder.AppendLine("Scopes - " + Scope?.AsSingleString()); + builder.AppendLine("Redirect Uri - " + RedirectUri?.OriginalString); + builder.AppendLine("Validate Authority? - " + ValidateAuthority); + builder.AppendLine("LoginHint provided? - " + !string.IsNullOrEmpty(LoginHint)); + builder.AppendLine("User provided? - " + (User != null)); + var dict = MsalHelpers.ParseKeyValueList(ExtraQueryParameters, '&', true, RequestContext); + builder.AppendLine("Extra Query Params Keys (space separated) - " + dict.Keys.AsSingleString()); + dict = MsalHelpers.ParseKeyValueList(SliceParameters, '&', true, RequestContext); + builder.AppendLine("Slice Parameters Keys(space separated) - " + dict.Keys.AsSingleString()); +#if DESKTOP || NETSTANDARD1_3 + builder.AppendLine("Confidential Client? - " + (ClientCredential != null)); + builder.AppendLine("Client Credential Request? - " + IsClientCredentialRequest); + if (IsClientCredentialRequest) + { + builder.AppendLine("Client Certificate Provided? - " + (ClientCredential.Certificate != null)); + } +#endif + RequestContext.Logger.InfoPii(builder.ToString()); + + // Create no Pii enabled string builder + builder = new StringBuilder(Environment.NewLine + "=== Request Data ===" + Environment.NewLine + + "Authority Provided? - " + (Authority != null) + Environment.NewLine); + builder.AppendLine("Scopes - " + Scope?.AsSingleString()); + builder.AppendLine("Validate Authority? - " + ValidateAuthority); + builder.AppendLine("LoginHint provided? - " + !string.IsNullOrEmpty(LoginHint)); + builder.AppendLine("User provided? - " + (User != null)); + dict = MsalHelpers.ParseKeyValueList(ExtraQueryParameters, '&', true, RequestContext); + builder.AppendLine("Extra Query Params Keys (space separated) - " + dict.Keys.AsSingleString()); + dict = MsalHelpers.ParseKeyValueList(SliceParameters, '&', true, RequestContext); + builder.AppendLine("Slice Parameters Keys(space separated) - " + dict.Keys.AsSingleString()); +#if DESKTOP || NETSTANDARD1_3 + builder.AppendLine("Confidential Client? - " + (ClientCredential != null)); + builder.AppendLine("Client Credential Request? - " + IsClientCredentialRequest); + if (IsClientCredentialRequest) + { + builder.AppendLine("Client Certificate Provided? - " + (ClientCredential.Certificate != null)); + } +#endif + RequestContext.Logger.Info(builder.ToString()); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta new file mode 100644 index 0000000..dcd5c26 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d03f0c3484d37534ea56b45ecb75567d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs new file mode 100644 index 0000000..616dc00 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class AuthorizationCodeRequest : RequestBase + { + public AuthorizationCodeRequest(AuthenticationRequestParameters authenticationRequestParameters) + : base(authenticationRequestParameters) + { + if (string.IsNullOrWhiteSpace(authenticationRequestParameters.AuthorizationCode)) + { + throw new ArgumentNullException(nameof(authenticationRequestParameters.AuthorizationCode)); + } + + PlatformPlugin.PlatformInformation.ValidateRedirectUri(authenticationRequestParameters.RedirectUri, + AuthenticationRequestParameters.RequestContext); + if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.RedirectUri.Fragment)) + { + throw new ArgumentException(MsalErrorMessage.RedirectUriContainsFragment, nameof(authenticationRequestParameters.RedirectUri)); + } + + LoadFromCache = false; + } + + protected override void SetAdditionalRequestParameters(OAuth2Client client) + { + client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.AuthorizationCode); + client.AddBodyParameter(OAuth2Parameter.Code, AuthenticationRequestParameters.AuthorizationCode); + client.AddBodyParameter(OAuth2Parameter.RedirectUri, + AuthenticationRequestParameters.RedirectUri.OriginalString); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta new file mode 100644 index 0000000..4fb3aeb --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25bd8a7eea3224741a9016f5aad62c06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs new file mode 100644 index 0000000..5a28fd5 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs @@ -0,0 +1,72 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class ClientCredentialRequest : RequestBase + { + public ClientCredentialRequest(AuthenticationRequestParameters authenticationRequestParameters, bool forceRefresh) + : base(authenticationRequestParameters) + { + ForceRefresh = forceRefresh; + } + + protected override SortedSet GetDecoratedScope(SortedSet inputScope) + { + return inputScope; + } + + internal override Task PreTokenRequestAsync() + { + // look for access token in the cache first. + if (!ForceRefresh && LoadFromCache) + { + AccessTokenItem + = TokenCache.FindAccessToken(AuthenticationRequestParameters); + } + + return CompletedTask; + } + protected override async Task SendTokenRequestAsync() + { + if (AccessTokenItem == null) + { + await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); + await base.SendTokenRequestAsync().ConfigureAwait(false); + } + } + + protected override void SetAdditionalRequestParameters(OAuth2Client client) + { + client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.ClientCredentials); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta new file mode 100644 index 0000000..713fce7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5705e0a64be19f4c9fa5fa73389c1a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs new file mode 100644 index 0000000..776b5c3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs @@ -0,0 +1,274 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.Interfaces; +using Microsoft.Identity.Client.Internal.OAuth2; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class InteractiveRequest : RequestBase + { + private readonly SortedSet _extraScopesToConsent; + private readonly UIBehavior _UIBehavior; + private readonly IWebUI _webUi; + private AuthorizationResult _authorizationResult; + private string _codeVerifier; + private string _state; + + public InteractiveRequest(AuthenticationRequestParameters authenticationRequestParameters, + IEnumerable extraScopesToConsent, UIBehavior UIBehavior, IWebUI webUI) + : this( + authenticationRequestParameters, extraScopesToConsent, authenticationRequestParameters.User?.DisplayableId, + UIBehavior, webUI) + { + } + + public InteractiveRequest(AuthenticationRequestParameters authenticationRequestParameters, + IEnumerable extraScopesToConsent, string loginHint, + UIBehavior UIBehavior, IWebUI webUI) + : base(authenticationRequestParameters) + { + PlatformPlugin.PlatformInformation.ValidateRedirectUri(authenticationRequestParameters.RedirectUri, + authenticationRequestParameters.RequestContext); + if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.RedirectUri.Fragment)) + { + throw new ArgumentException(MsalErrorMessage.RedirectUriContainsFragment, nameof(authenticationRequestParameters.RedirectUri)); + } + + _extraScopesToConsent = new SortedSet(); + if (!MsalHelpers.IsNullOrEmpty(extraScopesToConsent)) + { + _extraScopesToConsent = extraScopesToConsent.CreateSetFromEnumerable(); + } + + ValidateScopeInput(_extraScopesToConsent); + + authenticationRequestParameters.LoginHint = loginHint; + if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.ExtraQueryParameters) && + authenticationRequestParameters.ExtraQueryParameters[0] == '&') + { + authenticationRequestParameters.ExtraQueryParameters = + authenticationRequestParameters.ExtraQueryParameters.Substring(1); + } + + _webUi = webUI; + _UIBehavior = UIBehavior; + LoadFromCache = false; //no cache lookup and refresh for interactive. + var msg = "Additional scopes - " + _extraScopesToConsent.AsSingleString() + ";" + "UIBehavior - " + + _UIBehavior.PromptValue; + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + } + + protected override string GetUIBehaviorPromptValue() + { + return _UIBehavior.PromptValue; + } + + internal override async Task PreTokenRequestAsync() + { + await base.PreTokenRequestAsync().ConfigureAwait(false); + await AcquireAuthorizationAsync().ConfigureAwait(false); + VerifyAuthorizationResult(); + } + + internal async Task AcquireAuthorizationAsync() + { + Uri authorizationUri = CreateAuthorizationUri(true, true); + var uiEvent = new UiEvent(); + Client.Telemetry.GetInstance().StartEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, uiEvent); + try + { + _authorizationResult = await + _webUi.AcquireAuthorizationAsync(authorizationUri, AuthenticationRequestParameters.RedirectUri, + AuthenticationRequestParameters.RequestContext) + .ConfigureAwait(false); + uiEvent.UserCancelled = _authorizationResult.Status == AuthorizationStatus.UserCancel; + } + finally + { + Client.Telemetry.GetInstance().StopEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, uiEvent); + } + } + + internal async Task CreateAuthorizationUriAsync() + { + //this method is used in confidential clients to create authorization URLs. + await AuthenticationRequestParameters.Authority.ResolveEndpointsAsync(AuthenticationRequestParameters.LoginHint, AuthenticationRequestParameters.RequestContext).ConfigureAwait(false); + return CreateAuthorizationUri(); + } + + protected override void SetAdditionalRequestParameters(OAuth2Client client) + { + client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.AuthorizationCode); + client.AddBodyParameter(OAuth2Parameter.Code, _authorizationResult.Code); + client.AddBodyParameter(OAuth2Parameter.RedirectUri, AuthenticationRequestParameters.RedirectUri.OriginalString); + client.AddBodyParameter(OAuth2Parameter.CodeVerifier, _codeVerifier); + } + + private Uri CreateAuthorizationUri(bool addVerifier = false, bool addState = false) + { + IDictionary requestParameters = CreateAuthorizationRequestParameters(); + + if (addVerifier) + { + _codeVerifier = CryptographyHelper.GenerateCodeVerifier(); + string codeVerifierHash = CryptographyHelper.CreateBase64UrlEncodedSha256Hash(_codeVerifier); + + requestParameters[OAuth2Parameter.CodeChallenge] = codeVerifierHash; + requestParameters[OAuth2Parameter.CodeChallengeMethod] = OAuth2Value.CodeChallengeMethodValue; + } + + if (addState) + { + _state = Guid.NewGuid().ToString(); + requestParameters[OAuth2Parameter.State] = _state; + } + + //add uid/utid values to QP if user object was passed in. + if (AuthenticationRequestParameters.User != null) + { + if (!string.IsNullOrEmpty(AuthenticationRequestParameters.User.DisplayableId)) + { + requestParameters[OAuth2Parameter.LoginHint] = AuthenticationRequestParameters.User.DisplayableId; + } + + AuthenticationRequestParameters.ClientInfo = ClientInfo.CreateFromEncodedString(AuthenticationRequestParameters.User.Identifier); + + if (!string.IsNullOrEmpty(AuthenticationRequestParameters.ClientInfo.UniqueIdentifier)) + { + requestParameters[OAuth2Parameter.LoginReq] = AuthenticationRequestParameters.ClientInfo.UniqueIdentifier; + } + + if (!string.IsNullOrEmpty(AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier)) + { + requestParameters[OAuth2Parameter.DomainReq] = AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier; + } + } + + CheckForDuplicateQueryParameters(AuthenticationRequestParameters.ExtraQueryParameters, requestParameters); + CheckForDuplicateQueryParameters(AuthenticationRequestParameters.SliceParameters, requestParameters); + + string qp = requestParameters.ToQueryParameter(); + UriBuilder builder = + new UriBuilder(new Uri(AuthenticationRequestParameters.Authority.AuthorizationEndpoint)); + builder.AppendQueryParameters(qp); + + return builder.Uri; + } + + private void CheckForDuplicateQueryParameters(string queryParams, IDictionary requestParameters) + { + if (!string.IsNullOrWhiteSpace(queryParams)) + { + // Checks for _extraQueryParameters duplicating standard parameters + Dictionary kvps = + MsalHelpers.ParseKeyValueList(queryParams, '&', false, + AuthenticationRequestParameters.RequestContext); + + foreach (KeyValuePair kvp in kvps) + { + if (requestParameters.ContainsKey(kvp.Key)) + { + throw new MsalClientException(MsalClientException.DuplicateQueryParameterError, + string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.DuplicateQueryParameterTemplate, + kvp.Key)); + } + + requestParameters[kvp.Key] = kvp.Value; + } + } + } + + private Dictionary CreateAuthorizationRequestParameters() + { + SortedSet unionScope = + GetDecoratedScope( + new SortedSet(AuthenticationRequestParameters.Scope.Union(_extraScopesToConsent))); + + Dictionary authorizationRequestParameters = new Dictionary(); + authorizationRequestParameters[OAuth2Parameter.Scope] = unionScope.AsSingleString(); + authorizationRequestParameters[OAuth2Parameter.ResponseType] = OAuth2ResponseType.Code; + + authorizationRequestParameters[OAuth2Parameter.ClientId] = AuthenticationRequestParameters.ClientId; + authorizationRequestParameters[OAuth2Parameter.RedirectUri] = + AuthenticationRequestParameters.RedirectUri.OriginalString; + + if (!string.IsNullOrWhiteSpace(AuthenticationRequestParameters.LoginHint)) + { + authorizationRequestParameters[OAuth2Parameter.LoginHint] = AuthenticationRequestParameters.LoginHint; + } + + if (!string.IsNullOrEmpty(AuthenticationRequestParameters.RequestContext?.CorrelationId)) + { + authorizationRequestParameters[OAuth2Parameter.CorrelationId] = AuthenticationRequestParameters.RequestContext.CorrelationId; + } + + IDictionary adalIdParameters = MsalIdHelper.GetMsalIdParameters(); + foreach (KeyValuePair kvp in adalIdParameters) + { + authorizationRequestParameters[kvp.Key] = kvp.Value; + } + + authorizationRequestParameters[OAuth2Parameter.Prompt] = _UIBehavior.PromptValue; + return authorizationRequestParameters; + } + + private void VerifyAuthorizationResult() + { + if (_authorizationResult.Status == AuthorizationStatus.Success && !_state.Equals(_authorizationResult.State)) + { + throw new MsalClientException(MsalClientException.StateMismatchError, + string.Format(CultureInfo.InvariantCulture, "Returned state({0}) from authorize endpoint is not the same as the one sent({1})", _authorizationResult.State, _state)); + } + + if (_authorizationResult.Error == OAuth2Error.LoginRequired) + { + throw new MsalUiRequiredException(MsalUiRequiredException.NoPromptFailedError, + MsalErrorMessage.NoPromptFailedErrorMessage); + } + + if (_authorizationResult.Status == AuthorizationStatus.UserCancel) + { + throw new MsalClientException(_authorizationResult.Error, + _authorizationResult.ErrorDescription); + } + + if (_authorizationResult.Status != AuthorizationStatus.Success) + { + throw new MsalServiceException(_authorizationResult.Error, + _authorizationResult.ErrorDescription); + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta new file mode 100644 index 0000000..22aac0d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2629c1ec4acd3704c9b1bf4ba9f0bed2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs new file mode 100644 index 0000000..0df270b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class OnBehalfOfRequest : RequestBase + { + public OnBehalfOfRequest(AuthenticationRequestParameters authenticationRequestParameters) + : base(authenticationRequestParameters) + { + if (authenticationRequestParameters.UserAssertion == null) + { + throw new ArgumentNullException(nameof(authenticationRequestParameters.UserAssertion)); + } + } + + internal override async Task PreTokenRequestAsync() + { + await base.PreTokenRequestAsync().ConfigureAwait(false); + + // look for access token in the cache first. + // no access token is found, then it means token does not exist + // or new assertion has been passed. We should not use Refresh Token + // for the user because the new incoming token may have updated claims + // like mfa etc. + if (LoadFromCache) + { + AccessTokenItem + = TokenCache.FindAccessToken(AuthenticationRequestParameters); + } + } + + protected override async Task SendTokenRequestAsync() + { + if (AccessTokenItem == null) + { + await base.SendTokenRequestAsync().ConfigureAwait(false); + } + } + + protected override void SetAdditionalRequestParameters(OAuth2Client client) + { + client.AddBodyParameter(OAuth2Parameter.GrantType, + AuthenticationRequestParameters.UserAssertion.AssertionType); + client.AddBodyParameter(OAuth2Parameter.Assertion, AuthenticationRequestParameters.UserAssertion.Assertion); + client.AddBodyParameter(OAuth2Parameter.RequestedTokenUse, OAuth2RequestedTokenUse.OnBehalfOf); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta new file mode 100644 index 0000000..2a392fa --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81efa6aa48470c5409cfba16848e25dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs new file mode 100644 index 0000000..52e9a58 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs @@ -0,0 +1,315 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.Cache; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.OAuth2; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal abstract class RequestBase + { + protected static readonly Task CompletedTask = Task.FromResult(false); + internal readonly AuthenticationRequestParameters AuthenticationRequestParameters; + internal readonly TokenCache TokenCache; + protected TokenResponse Response; + protected AccessTokenCacheItem AccessTokenItem; + public ApiEvent.ApiIds ApiId { get; set; } + public bool IsConfidentialClient { get; set; } + protected virtual string GetUIBehaviorPromptValue() + { + return null; + } + + protected bool SupportADFS { get; set; } + + protected bool LoadFromCache { get; set; } + + protected bool ForceRefresh { get; set; } + + protected bool StoreToCache { get; set; } + + protected RequestBase(AuthenticationRequestParameters authenticationRequestParameters) + { + TokenCache = authenticationRequestParameters.TokenCache; + + // Log contains Pii + authenticationRequestParameters.RequestContext.Logger.InfoPii(string.Format(CultureInfo.InvariantCulture, + "=== Token Acquisition ({4}) started:\n\tAuthority: {0}\n\tScope: {1}\n\tClientId: {2}\n\tCache Provided: {3}", + authenticationRequestParameters?.Authority?.CanonicalAuthority, + authenticationRequestParameters.Scope.AsSingleString(), + authenticationRequestParameters.ClientId, + TokenCache != null, this.GetType().Name)); + + // Log does not contain Pii + var msg = string.Format(CultureInfo.InvariantCulture, + "=== Token Acquisition ({1}) started:\n\tCache Provided: {0}", TokenCache != null, this.GetType().Name); + + if (authenticationRequestParameters.Authority != null && + AadAuthority.IsInTrustedHostList(authenticationRequestParameters.Authority.Host)) + { + msg += string.Format(CultureInfo.CurrentCulture, "\n\tAuthority Host: {0}", + authenticationRequestParameters.Authority.Host); + } + authenticationRequestParameters.RequestContext.Logger.Info(msg); + + AuthenticationRequestParameters = authenticationRequestParameters; + if (authenticationRequestParameters.Scope == null || authenticationRequestParameters.Scope.Count == 0) + { + throw new ArgumentNullException(nameof(authenticationRequestParameters.Scope)); + } + + ValidateScopeInput(authenticationRequestParameters.Scope); + LoadFromCache = (TokenCache != null); + StoreToCache = (TokenCache != null); + SupportADFS = false; + + AuthenticationRequestParameters.LogState(); + Client.Telemetry.GetInstance().ClientId = AuthenticationRequestParameters.ClientId; + } + + protected virtual SortedSet GetDecoratedScope(SortedSet inputScope) + { + SortedSet set = new SortedSet(inputScope.ToArray()); + set.UnionWith(OAuth2Value.ReservedScopes.CreateSetFromEnumerable()); + return set; + } + + protected void ValidateScopeInput(SortedSet scopesToValidate) + { + //check if scope or additional scope contains client ID. + if (scopesToValidate.Intersect(OAuth2Value.ReservedScopes.CreateSetFromEnumerable()).Any()) + { + throw new ArgumentException("MSAL always sends the scopes 'openid profile offline_access'. " + + "They cannot be suppressed as they are required for the " + + "library to function. Do not include any of these scopes in the scope parameter."); + } + + if (scopesToValidate.Contains(AuthenticationRequestParameters.ClientId)) + { + throw new ArgumentException("API does not accept client id as a user-provided scope"); + } + } + + public async Task RunAsync() + { + //this method is the common entrance for all token requests, so it is a good place to put the generic Telemetry logic here + AuthenticationRequestParameters.RequestContext.TelemetryRequestId = Client.Telemetry.GetInstance().GenerateNewRequestId(); + var apiEvent = new ApiEvent() + { + ApiId = ApiId, + ValidationStatus = AuthenticationRequestParameters.ValidateAuthority.ToString(), + UserId = AuthenticationRequestParameters.User != null ? AuthenticationRequestParameters.User.Identifier : "", + CorrelationId = AuthenticationRequestParameters.RequestContext.CorrelationId, + RequestId = AuthenticationRequestParameters.RequestContext.TelemetryRequestId, + IsConfidentialClient = IsConfidentialClient, + UiBehavior = GetUIBehaviorPromptValue(), + WasSuccessful = false + }; + + if (AuthenticationRequestParameters.Authority != null) + { + apiEvent.Authority = new Uri(AuthenticationRequestParameters.Authority.CanonicalAuthority); + apiEvent.AuthorityType = AuthenticationRequestParameters.Authority.AuthorityType.ToString(); + } + + Client.Telemetry.GetInstance().StartEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, apiEvent); + + try + { + //authority endpoints resolution and validation + await PreTokenRequestAsync().ConfigureAwait(false); + await SendTokenRequestAsync().ConfigureAwait(false); + AuthenticationResult result = PostTokenRequest(); + await PostRunAsync(result).ConfigureAwait(false); + + apiEvent.TenantId = result.TenantId; + apiEvent.UserId = result.UniqueId; + apiEvent.WasSuccessful = true; + return result; + } + catch (MsalException ex) + { + apiEvent.ApiErrorCode = ex.ErrorCode; + AuthenticationRequestParameters.RequestContext.Logger.Error(ex); + AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(ex); + throw; + } + catch (Exception ex) + { + AuthenticationRequestParameters.RequestContext.Logger.Error(ex); + AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(ex); + throw; + } + finally + { + Client.Telemetry.GetInstance().StopEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, apiEvent); + Client.Telemetry.GetInstance().Flush(AuthenticationRequestParameters.RequestContext.TelemetryRequestId); + } + } + + private AccessTokenCacheItem SaveTokenResponseToCache() + { + // developer passed in user object. + string msg = "checking client info returned from the server.."; + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + + ClientInfo fromServer = null; + + if (!AuthenticationRequestParameters.IsClientCredentialRequest) + { + //client_info is not returned from client credential flows because there is no user present. + fromServer = ClientInfo.CreateFromJson(Response.ClientInfo); + } + + if (fromServer!= null && AuthenticationRequestParameters.ClientInfo != null) + { + if (!fromServer.UniqueIdentifier.Equals(AuthenticationRequestParameters.ClientInfo.UniqueIdentifier) || + !fromServer.UniqueTenantIdentifier.Equals(AuthenticationRequestParameters.ClientInfo + .UniqueTenantIdentifier)) + { + AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(String.Format( + CultureInfo.InvariantCulture, + "Returned user identifiers (uid:{0} utid:{1}) does not meatch the sent user identifier (uid:{2} utid:{3})", + fromServer.UniqueIdentifier, fromServer.UniqueTenantIdentifier, + AuthenticationRequestParameters.ClientInfo.UniqueIdentifier, + AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier)); + + AuthenticationRequestParameters.RequestContext.Logger.Error("Returned user identifiers do not match the sent user" + + "identifier"); + + throw new MsalServiceException("user_mismatch", "Returned user identifier does not match the sent user identifier"); + } + } + + IdToken idToken = IdToken.Parse(Response.IdToken); + AuthenticationRequestParameters.TenantUpdatedCanonicalAuthority = Authority.UpdateTenantId( + AuthenticationRequestParameters.Authority.CanonicalAuthority, idToken?.TenantId); + + if (StoreToCache) + { + msg = "Saving Token Response to cache.."; + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + + return TokenCache.SaveAccessAndRefreshToken(AuthenticationRequestParameters, Response); + } + + return new AccessTokenCacheItem(AuthenticationRequestParameters.TenantUpdatedCanonicalAuthority, + AuthenticationRequestParameters.ClientId, Response); + } + + protected virtual Task PostRunAsync(AuthenticationResult result) + { + LogReturnedToken(result); + return CompletedTask; + } + + internal virtual async Task PreTokenRequestAsync() + { + await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); + } + + + internal async Task ResolveAuthorityEndpointsAsync() + { + await AuthenticationRequestParameters.Authority + .ResolveEndpointsAsync(AuthenticationRequestParameters.LoginHint, + AuthenticationRequestParameters.RequestContext) + .ConfigureAwait(false); + } + + + protected virtual AuthenticationResult PostTokenRequest() + { + //save to cache if no access token item found + //this means that no cached item was found + if (AccessTokenItem == null) + { + AccessTokenItem = SaveTokenResponseToCache(); + } + + return new AuthenticationResult(AccessTokenItem); + } + + protected abstract void SetAdditionalRequestParameters(OAuth2Client client); + + protected virtual async Task SendTokenRequestAsync() + { + OAuth2Client client = new OAuth2Client(); + client.AddBodyParameter(OAuth2Parameter.ClientId, AuthenticationRequestParameters.ClientId); + client.AddBodyParameter(OAuth2Parameter.ClientInfo, "1"); + foreach (var entry in AuthenticationRequestParameters.ToParameters()) + { + client.AddBodyParameter(entry.Key, entry.Value); + } + + client.AddBodyParameter(OAuth2Parameter.Scope, + GetDecoratedScope(AuthenticationRequestParameters.Scope).AsSingleString()); + SetAdditionalRequestParameters(client); + await SendHttpMessageAsync(client).ConfigureAwait(false); + } + + private async Task SendHttpMessageAsync(OAuth2Client client) + { + UriBuilder builder = new UriBuilder(AuthenticationRequestParameters.Authority.TokenEndpoint); + builder.AppendQueryParameters(AuthenticationRequestParameters.SliceParameters); + Response = + await client + .GetTokenAsync(builder.Uri, + AuthenticationRequestParameters.RequestContext) + .ConfigureAwait(false); + + if (string.IsNullOrEmpty(Response.Scope)) + { + Response.Scope = AuthenticationRequestParameters.Scope.AsSingleString(); + const string msg = "ScopeSet was missing from the token response, so using developer provided scopes in the result"; + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + + } + } + + private void LogReturnedToken(AuthenticationResult result) + { + if (result.AccessToken != null) + { + var msg = string.Format(CultureInfo.InvariantCulture, "=== Token Acquisition finished successfully. An access token was returned with Expiration Time: {0} ===", + result.ExpiresOn); + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta new file mode 100644 index 0000000..760640b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bb114f9b17f2e34f8f55bd2fb3409fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs new file mode 100644 index 0000000..cb5eb0e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.OAuth2; +using Microsoft.Identity.Client.Internal.Cache; + +namespace Microsoft.Identity.Client.Internal.Requests +{ + internal class SilentRequest : RequestBase + { + private RefreshTokenCacheItem _refreshTokenItem; + + public SilentRequest(AuthenticationRequestParameters authenticationRequestParameters, bool forceRefresh) + : base(authenticationRequestParameters) + { + if (authenticationRequestParameters.User == null) + { + throw new MsalUiRequiredException(MsalUiRequiredException.UserNullError, "Null user was passed in AcquiretokenSilent API. Pass in " + + "a user object or call acquireToken authenticate."); + } + + ForceRefresh = forceRefresh; + } + + protected override void SetAdditionalRequestParameters(OAuth2Client client) + { + client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.RefreshToken); + client.AddBodyParameter(OAuth2Parameter.RefreshToken, _refreshTokenItem.RefreshToken); + } + + internal override async Task PreTokenRequestAsync() + { + if (!LoadFromCache) + { + throw new MsalUiRequiredException(MsalUiRequiredException.TokenCacheNullError, + "Token cache is set to null. Silent requests cannot be executed."); + } + + //look for access token. + AccessTokenItem + = TokenCache.FindAccessToken(AuthenticationRequestParameters); + + if (ForceRefresh) + { + AccessTokenItem = null; + } + + await CompletedTask.ConfigureAwait(false); + } + + protected override async Task SendTokenRequestAsync() + { + if (AccessTokenItem == null) + { + _refreshTokenItem = + TokenCache.FindRefreshToken(AuthenticationRequestParameters); + + if (_refreshTokenItem == null) + { + const string msg = "No Refresh Token was found in the cache"; + AuthenticationRequestParameters.RequestContext.Logger.Verbose(msg); + AuthenticationRequestParameters.RequestContext.Logger.VerbosePii(msg); + + throw new MsalUiRequiredException(MsalUiRequiredException.NoTokensFoundError, + "No Refresh Token found in the cache"); + } + + AuthenticationRequestParameters.RequestContext.Logger.Verbose("Refreshing access token..."); + await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); + await base.SendTokenRequestAsync().ConfigureAwait(false); + + if (Response.RefreshToken == null) + { + Response.RefreshToken = _refreshTokenItem.RefreshToken; + const string msg = "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead"; + AuthenticationRequestParameters.RequestContext.Logger.Info(msg); + AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); + } + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta new file mode 100644 index 0000000..a44b4f4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3cc06d1c95ecb0c429b51f64e52422c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta new file mode 100644 index 0000000..a3a65d4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 934fef8613a74304cb23290708437023 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs new file mode 100644 index 0000000..6fe3c1f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs @@ -0,0 +1,173 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + + +using System; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class ApiEvent : EventBase + { + public const string ApiIdKey = EventNamePrefix + "api_id"; + public const string AuthorityKey = EventNamePrefix + "authority"; + public const string AuthorityTypeKey = EventNamePrefix + "authority_type"; + public const string UiBehaviorKey = EventNamePrefix + "ui_behavior"; + public const string ValidationStatusKey = EventNamePrefix + "validation_status"; + public const string TenantIdKey = EventNamePrefix + "tenant_id"; + public const string UserIdKey = EventNamePrefix + "user_id"; + public const string WasSuccessfulKey = EventNamePrefix + "was_successful"; + public const string CorrelationIdKey = EventNamePrefix + "correlation_id"; + public const string RequestIdKey = EventNamePrefix + "request_id"; + public const string IsConfidentialClientKey = EventNamePrefix + "is_confidential_client"; + public const string ApiErrorCodeKey = EventNamePrefix + "api_error_code"; + + public enum ApiIds + { + AcquireTokenSilentWithAuthority = 31, + AcquireTokenSilentWithoutAuthority = 30, + + AcquireTokenWithScope = 170, + AcquireTokenWithScopeHint = 171, + AcquireTokenWithScopeHintBehavior = 172, + AcquireTokenWithScopeHintBehaviorAuthority = 173, + AcquireTokenWithScopeUser = 176, + AcquireTokenWithScopeUserBehavior = 174, + AcquireTokenWithScopeUserBehaviorAuthority = 175, + + AcquireTokenOnBehalfOfWithScopeUser = 520, + AcquireTokenOnBehalfOfWithScopeUserAuthority = 521, + + AcquireTokenForClientWithScope = 726, + AcquireTokenForClientWithScopeRefresh = 727, + + AcquireTokenByAuthorizationCodeWithCodeScope = 830, + } + + public ApiEvent() : base(EventNamePrefix + "api_event") { } + + public ApiIds ApiId + { + set + { + this[ApiIdKey] = ((int)value).ToStringInvariant(); + } + } + + public Uri Authority + { + set + { + this[AuthorityKey] = ScrubTenant(value)?.ToLowerInvariant(); + } + } + + public string AuthorityType + { + set + { + this[AuthorityTypeKey] = value?.ToLowerInvariant(); + } + } + + public string UiBehavior + { + set + { + this[UiBehaviorKey] = value?.ToLowerInvariant(); + } + } + + public string ValidationStatus + { + set + { + this[ValidationStatusKey] = value?.ToLowerInvariant(); + } + } + + public string TenantId + { + set + { + this[TenantIdKey] = value != null && Logger.PiiLoggingEnabled ? CryptographyHelper.CreateBase64UrlEncodedSha256Hash(value) : null; + } + } + + public string UserId + { + set + { + this[UserIdKey] = value != null && Logger.PiiLoggingEnabled ? CryptographyHelper.CreateBase64UrlEncodedSha256Hash(value) : null; + } + } + + public bool WasSuccessful + { + set + { + this[WasSuccessfulKey] = value.ToString().ToLowerInvariant(); + } + + get + { + return this[WasSuccessfulKey] == true.ToString().ToLowerInvariant(); + } + } + + public string CorrelationId + { + set + { + this[CorrelationIdKey] = value; + } + } + + public string RequestId + { + set + { + this[RequestIdKey] = value; + } + } + + public bool IsConfidentialClient + { + set + { + this[IsConfidentialClientKey] = value.ToString().ToLowerInvariant(); + } + } + + public string ApiErrorCode + { + set + { + this[ApiErrorCodeKey] = value; + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta new file mode 100644 index 0000000..f6c68f0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1d296f68afaa5847a38f26a9b003b35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs new file mode 100644 index 0000000..135fb15 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs @@ -0,0 +1,67 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + + +using System.Collections.Generic; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class CacheEvent : EventBase + { + public const string TokenCacheLookup = EventNamePrefix + "token_cache_lookup"; + public const string TokenCacheWrite = EventNamePrefix + "token_cache_write"; + public const string TokenCacheBeforeAccess = EventNamePrefix + "token_cache_before_access"; + public const string TokenCacheAfterAccess = EventNamePrefix + "token_cache_after_access"; + public const string TokenCacheBeforeWrite = EventNamePrefix + "token_cache_before_write"; + public const string TokenCacheDelete = EventNamePrefix + "token_cache_delete"; + + public const string TokenTypeKey = EventNamePrefix + "token_type"; + + public CacheEvent(string eventName) : base(eventName) + { + } + + public enum TokenTypes + { + AT, + RT + }; + + public TokenTypes TokenType + { + set + { + var types = new Dictionary() + { + {TokenTypes.AT, "at"}, + {TokenTypes.RT, "rt"} + }; + this[TokenTypeKey] = types[value]; + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta new file mode 100644 index 0000000..773515b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f22d2f1a5561cbf438ee7d9bf4c4d8c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs new file mode 100644 index 0000000..dea3276 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs @@ -0,0 +1,45 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class DefaultEvent : EventBase + { + public DefaultEvent(string clientId) : base((string) (EventBase.EventNamePrefix + "default_event")) + { + this[EventNamePrefix + "client_id"] = clientId; + this[EventNamePrefix + "sdk_platform"] = PlatformPlugin.PlatformInformation.GetProductName()?.ToLowerInvariant(); + this[EventNamePrefix + "sdk_version"] = MsalIdHelper.GetMsalVersion(); + // TODO: The following implementation will be used after the 3 helpers being implemented (in a separated PR) + // this[EventNamePrefix + "application_name"] = MsalIdHelper.GetApplicationName(); // Not yet implemented + // this[EventNamePrefix + "application_version"] = MsalIdHelper.GetApplicationVersion(); // Not yet implemented + // this[EventNamePrefix + "device_id"] = MsalIdHelper.GetDeviceId(); // Not yet implemented + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta new file mode 100644 index 0000000..2b378bb --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73826c4a534e8b1469fe3ace0d05082e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs new file mode 100644 index 0000000..03e0c84 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Instance; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal abstract class EventBase : Dictionary + { + protected const string EventNamePrefix = "msal."; + public const string EventNameKey = EventNamePrefix + "event_name"; + public const string StartTimeKey = EventNamePrefix + "start_time"; + public const string ElapsedTimeKey = EventNamePrefix + "elapsed_time"; + private readonly long _startTimestamp; + + public const string TenantPlaceHolder = ""; // It is used to replace the real tenant in telemetry info + + public EventBase(string eventName) : this(eventName, new Dictionary()) {} + + protected static long CurrentUnixTimeMilliseconds() + { + return MsalHelpers.DateTimeToUnixTimestampMilliseconds(DateTimeOffset.Now); + } + + public EventBase(string eventName, IDictionary predefined) : base(predefined) + { + this[EventNameKey] = eventName; + _startTimestamp = CurrentUnixTimeMilliseconds(); + this[StartTimeKey] = _startTimestamp.ToStringInvariant(); + this[ElapsedTimeKey] = "-1"; + } + + public void Stop() + { + this[ElapsedTimeKey] = (CurrentUnixTimeMilliseconds() - _startTimestamp).ToStringInvariant(); // It is a duration + } + + public static string ScrubTenant(Uri uri) // Note: There is also a Unit Test case for this helper + { + if (!uri.IsAbsoluteUri) + { + throw new ArgumentException("Requires an absolute uri"); + } + if (!AadAuthority.IsInTrustedHostList(uri.Host)) // only collect telemetry for well-known hosts + { + return null; + } + + var pieces = uri.AbsolutePath.Split('/'); // It looks like {"", "common", "oauth2", "v2.0", "token"} + if (pieces.Length >= 2) + { + int tenantPosition = pieces[1] == B2CAuthority.Prefix ? 2 : 1; + if (tenantPosition < pieces.Length) + { + // Replace it rather than remove it. Otherwise the end result would misleadingly look like a complete URL while it is actually not. + pieces[tenantPosition] = TenantPlaceHolder; + } + } + string scrubbedPath = String.Join("/", pieces); + return uri.Scheme + "://" + uri.Authority + scrubbedPath; + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta new file mode 100644 index 0000000..46cbe8f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 146a9cf6465409543ae8c26dcdbda5d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs new file mode 100644 index 0000000..83c0184 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + + +using System; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class HttpEvent : EventBase + { + public const string HttpPathKey = EventNamePrefix + "http_path"; + public const string UserAgentKey = EventNamePrefix + "user_agent"; + public const string QueryParametersKey = EventNamePrefix + "query_parameters"; + public const string ApiVersionKey = EventNamePrefix + "api_version"; + public const string ResponseCodeKey = EventNamePrefix + "response_code"; + public const string OauthErrorCodeKey = EventNamePrefix + "oauth_error_code"; + + public HttpEvent() : base(EventNamePrefix + "http_event") { } + + public Uri HttpPath + { + set + { + this[HttpPathKey] = ScrubTenant(value); + } + } + + public string UserAgent + { + set + { + this[UserAgentKey] = value; + } + } + + public string QueryParams + { + set + { + this[QueryParametersKey] = String.Join( // query parameters are case-sensitive + "&", MsalHelpers.ParseKeyValueList(value, '&', false, true, null).Keys); // It turns out ParseKeyValueList(..., null) is valid + } + } + + public string ApiVersion + { + set + { + this[ApiVersionKey] = value?.ToLowerInvariant(); + } + } + + public int HttpResponseStatus + { + set + { + this[ResponseCodeKey] = value.ToStringInvariant(); + } + } + + public string OauthErrorCode + { + set + { + this[OauthErrorCodeKey] = value; + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta new file mode 100644 index 0000000..a487bea --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13fc505878f8794418d86bd659c49774 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs new file mode 100644 index 0000000..b50685c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs @@ -0,0 +1,92 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client; + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class TelemetryTokenCacheAccessor : TokenCacheAccessor + { + // The content of this class has to be placed outside of its base class TokenCacheAccessor, + // otherwise we would have to modify multiple implementations of TokenCacheAccessor on different platforms. + public void SaveAccessToken(string cacheKey, string item, RequestContext requestContext) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheWrite) { TokenType = CacheEvent.TokenTypes.AT }; + Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); + try + { + SaveAccessToken(cacheKey, item); + } + finally + { + Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); + } + } + + public void SaveRefreshToken(string cacheKey, string item, RequestContext requestContext) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheWrite) { TokenType = CacheEvent.TokenTypes.RT }; + Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); + try + { + SaveRefreshToken(cacheKey, item); + } + finally + { + Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); + } + } + + public void DeleteAccessToken(string cacheKey, RequestContext requestContext) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheDelete) { TokenType = CacheEvent.TokenTypes.AT }; + Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); + try + { + DeleteAccessToken(cacheKey); + } + finally + { + Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); + } + } + + public void DeleteRefreshToken(string cacheKey, RequestContext requestContext) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheDelete) { TokenType = CacheEvent.TokenTypes.RT }; + Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); + try + { + DeleteRefreshToken(cacheKey); + } + finally + { + Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta new file mode 100644 index 0000000..fae90c7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e84a3a1ded71c1f45bdf664632acbb64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs new file mode 100644 index 0000000..4aa34f2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs @@ -0,0 +1,45 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + + +namespace Microsoft.Identity.Client.Internal.Telemetry +{ + internal class UiEvent : EventBase + { + public const string UserCancelledKey = EventNamePrefix + "user_cancelled"; + + public UiEvent() : base(EventNamePrefix + "ui_event") { } + + public bool UserCancelled + { + set + { + this[UserCancelledKey] = value.ToString().ToLowerInvariant(); + } + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta new file mode 100644 index 0000000..834e5c1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26180f0febbf25e4eb3a1c9c369c6b72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs new file mode 100644 index 0000000..011ebc4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs @@ -0,0 +1,267 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using Microsoft.Identity.Client.Internal; +using Exception = System.Exception; + +namespace Microsoft.Identity.Client +{ + /// + /// Callback delegate that allows the developer to consume logs handle them in a custom manner. + /// + /// Log level of the message + /// Pre-formatted log message + /// Indicates if the log message contains PII. If Logger.PiiLoggingEnabled is set to + /// false then this value is always false. + public delegate void LogCallback(Logger.LogLevel level, string message, bool containsPii); + + /// + /// MSAL Logger class that allows developers to configure log level, configure callbacks etc. + /// + public sealed class Logger + { + /// + /// MSAL Log Levels + /// + public enum LogLevel + { + /// + /// Error Log level + /// + Error = 0, + + /// + /// Warning Log level + /// + Warning = 1, + + /// + /// Information Log level + /// + Info = 2, + + /// + /// Verbose Log level + /// + Verbose = 3 + } + + internal Logger(Guid correlationId, string component) + { + CorrelationId = correlationId; + + Component = string.Empty; + if (!string.IsNullOrEmpty(component)) + { + //space is intentional for formatting of the message + Component = string.Format(CultureInfo.InvariantCulture, " ({0})", component); + } + } + + internal string Component { get; set; } + + private Guid CorrelationId { get; set; } + + private static readonly object LockObj = new object(); + + private static volatile LogCallback _logCallback; + /// + /// Callback instance that can be provided by the developer to consume and publish logs in a custom manner. + /// The property can only be set once and it will throw an ArgumentException if called twice. + /// + public static LogCallback LogCallback + { + set + { + lock (LockObj) + { + if (_logCallback != null) + { + throw new ArgumentException("MSAL logging callback can only be set once per process and" + + " should never change once set."); + } + + _logCallback = value; + } + } + } + + /// + /// Configurable log level. Default value is Info. + /// + public static LogLevel Level { get; set; } = LogLevel.Info; + + /// + /// Flag to enable/disable logging of PII data. PII logs are never written to default outputs like Console, Logcat or NSLog. + /// Default is set to false. + /// + public static bool PiiLoggingEnabled { get; set; } = false; + + /// + /// Flag to enable/disable logging to platform defaults. In Desktop/UWP, Event Tracing is used. In iOS, NSLog is used. + /// In android, logcat is used. + /// + internal static bool DefaultLoggingEnabled { get; set; } = false; + + internal static void ExecuteCallback(LogLevel level, string message, bool containsPii) + { + lock (LockObj) + { + _logCallback?.Invoke(level, message, containsPii); + } + } + + #region LogMessages + /// + /// Method for error logging + /// + internal void Error(string message) + { + LogMessage(message, LogLevel.Error, false); + } + + /// + /// Method for error logging of Pii + /// + internal void ErrorPii(string message) + { + LogMessage(message, LogLevel.Error, true); + } + + /// + /// Method for warning logging + /// + internal void Warning(string message) + { + LogMessage(message, LogLevel.Warning, false); + } + + /// + /// Method for warning logging of Pii + /// + internal void WarningPii(string message) + { + LogMessage(message, LogLevel.Warning, true); + } + + /// + /// Method for information logging + /// + internal void Info(string message) + { + LogMessage(message, LogLevel.Info, false); + } + + /// + /// Method for information logging for Pii + /// + internal void InfoPii(string message) + { + LogMessage(message, LogLevel.Info, true); + } + + /// + /// Method for verbose logging + /// + internal void Verbose(string message) + { + LogMessage(message, LogLevel.Verbose, false); + } + + /// + /// Method for verbose logging for Pii + /// + internal void VerbosePii(string message) + { + LogMessage(message, LogLevel.Verbose, true); + } + + /// + /// Method for error exception logging + /// Removes Pii from exception + /// + internal void Error(Exception ex) + { + Error(ex.GetPiiScrubbedDetails()); + } + + /// + /// Method for error exception logging for Pii + /// Contains Pii passed from exception + /// + internal void ErrorPii(Exception ex) + { + ErrorPii(ex.ToString()); + } + + #endregion + + private void LogMessage(string logMessage, LogLevel logLevel, bool containsPii) + { + if ((logLevel > Level) || (!PiiLoggingEnabled && containsPii)) + { + return; + } + + //format log message; + string correlationId = (CorrelationId.Equals(Guid.Empty)) + ? string.Empty + : " - " + CorrelationId; + + string os = "N/A"; + if (MsalIdHelper.GetMsalIdParameters().ContainsKey(MsalIdParameter.OS)) + { + os = MsalIdHelper.GetMsalIdParameters()[MsalIdParameter.OS]; + } + + string log = string.Format(CultureInfo.InvariantCulture, "MSAL {0} {1} {2} [{3}{4}]{5} {6}", + MsalIdHelper.GetMsalVersion(), + MsalIdHelper.GetMsalIdParameters()[MsalIdParameter.Product], + os, DateTime.UtcNow, correlationId, Component, logMessage); + + if (PiiLoggingEnabled && containsPii) + { + const string piiLogMsg = "(True) "; + log = piiLogMsg + log; + } + else + { + const string noPiiLogMsg = "(False) "; + log = noPiiLogMsg + log; + } + + if (DefaultLoggingEnabled) + { + PlatformPlugin.LogMessage(logLevel, log); + } + + ExecuteCallback(logLevel, log, containsPii); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta new file mode 100644 index 0000000..bed90e7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f67aee32795848d43b68b281cf6a95aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs new file mode 100644 index 0000000..9a6bfc3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs @@ -0,0 +1,151 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Globalization; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client +{ + /// + /// This exception class represents errors that are local to the library or the device. + /// + public class MsalClientException : MsalException + { + /// + /// MultipleTokensMatched were matched. + /// + public const string MultipleTokensMatchedError = "multiple_matching_tokens_detected"; + + /// + /// Non HTTPS redirects are not supported. + /// + public const string NonHttpsRedirectNotSupported = "non_https_redirect_failed"; + + /// + /// The request could not be preformed because the network is down. + /// + public const string NetworkNotAvailableError = "network_not_available"; + + /// + /// Duplicate query parameter in extraQueryParameters + /// + public const string DuplicateQueryParameterError = "duplicate_query_parameter"; + + + /// + /// The request could not be preformed because of a failure in the UI flow. + /// + public const string AuthenticationUiFailedError = "authentication_ui_failed"; + + /// + /// Authentication canceled. + /// + public const string AuthenticationCanceledError = "authentication_canceled"; + + /// + /// JSON parsing failed. + /// + public const string JsonParseError = "json_parse_failed"; + + /// + /// JWT was invalid + /// + public const string InvalidJwtError = "invalid_jwt"; + + /// + /// State returned from the STS was different than the one sent. + /// + public const string StateMismatchError = "state_mismatch"; + + /// + /// Tenant discovery failed. + /// + public const string TenantDiscoveryFailedError = "tenant_discovery_failed"; + +#if ANDROID + + /// + /// Indicates that chrome is not installed on the device. The sdk uses chrome custom tab for + /// authorize request if applicable or fall back to chrome browser. + /// + public const string ChromeNotInstalledError = "chrome_not_installed"; + + /// + /// Indicates that chrome is installed on the device but disabled. The sdk uses chrome custom tab for + /// authorize request if applicable or fall back to chrome browser. + /// + public const string ChromeDisabledError = "chrome_disabled"; + + /// + /// The intent to launch AuthenticationActivity is not resolvable by the OS or the intent. + /// + public const string UnresolvableIntentError = "unresolvable_intent"; + +#endif + + + /// + /// Initializes a new instance of the exception class with a specified + /// error code. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + public MsalClientException(string errorCode) : base(errorCode) + { + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code and error message. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + public MsalClientException(string errorCode, string errorMessage):base(errorCode, errorMessage) + { + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and inner exception. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + /// + public MsalClientException(string errorCode, string errorMessage, Exception innerException):base(errorCode, errorMessage, innerException) + { + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta new file mode 100644 index 0000000..8d76f9c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 017698f87adacf0448469eb563550907 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs new file mode 100644 index 0000000..2c13181 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client +{ + /// + /// The exception type thrown when an error occurs during token acquisition. + /// + public class MsalException : Exception + { + + /// + /// Unknown Error occured. + /// + public const string UnknownError = "unknown_error"; + + /// + /// Initializes a new instance of the exception class. + /// + public MsalException() + : base(MsalErrorMessage.Unknown) + { + ErrorCode = UnknownError; + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + public MsalException(string errorCode) + { + ErrorCode = errorCode; + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code and error message. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + public MsalException(string errorCode, string errorMessage) + : base(errorMessage) + { + ErrorCode = errorCode; + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + /// + /// The exception that is the cause of the current exception, or a null reference if no inner + /// exception is specified. + /// + public MsalException(string errorCode, string errorMessage, Exception innerException) + : base(errorMessage, innerException) + { + ErrorCode = errorCode; + } + + /// + /// Gets the protocol error code returned by the service or generated by client. This is the code you can rely on for + /// exception handling. + /// + public string ErrorCode { get; } + + /// + /// Creates and returns a string representation of the current exception. + /// + /// A string representation of the current exception. + public override string ToString() + { + return base.ToString() + string.Format(CultureInfo.InvariantCulture, "\n\tErrorCode: {0}", ErrorCode); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta new file mode 100644 index 0000000..2043e41 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f7d89c5853f1cb4a84dcbe6d1f1da83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs new file mode 100644 index 0000000..f9e4ee2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs @@ -0,0 +1,178 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; + +namespace Microsoft.Identity.Client +{ + /// + /// The exception type thrown when service returns and error response or other networking errors occur. + /// + public class MsalServiceException : MsalException + { + /// + /// Service is unavailable and returned HTTP error code within the range of 500-599. + /// + public const string ServiceNotAvailable = "service_not_available"; + + /// + /// Http Request timed out. + /// + public const string RequestTimeout = "request_timeout"; + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The protocol error code returned by the service or generated by client. This is the code you + /// can rely on for exception handling. + /// + /// The error message that explains the reason for the exception. + public MsalServiceException(string errorCode, string errorMessage) + : base( + errorCode, errorMessage) + { + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The protocol error code returned by the service or generated by client. This is the code you + /// can rely on for exception handling. + /// + /// The error message that explains the reason for the exception. + /// Status code of the resposne received from the service. + public MsalServiceException(string errorCode, string errorMessage, int statusCode) + : this(errorCode, errorMessage) + { + StatusCode = statusCode; + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The protocol error code returned by the service or generated by client. This is the code you + /// can rely on for exception handling. + /// + /// The error message that explains the reason for the exception. + /// + /// The exception that is the cause of the current exception, or a null reference if no inner + /// exception is specified. + /// + public MsalServiceException(string errorCode, string errorMessage, + Exception innerException) + : base( + errorCode, errorMessage, innerException) + { + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The protocol error code returned by the service or generated by client. This is the code you + /// can rely on for exception handling. + /// + /// The error message that explains the reason for the exception. + /// Status code of the resposne received from the service. + /// + /// The exception that is the cause of the current exception, or a null reference if no inner + /// exception is specified. + /// + public MsalServiceException(string errorCode, string errorMessage, int statusCode, + Exception innerException) + : base( + errorCode, errorMessage, innerException) + { + StatusCode = statusCode; + } + + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// + /// The protocol error code returned by the service or generated by client. This is the code you + /// can rely on for exception handling. + /// + /// The error message that explains the reason for the exception. + /// The status code of the request. + /// The claims challenge returned back from the service. + /// + /// The exception that is the cause of the current exception, or a null reference if no inner + /// exception is specified. + /// + public MsalServiceException(string errorCode, string errorMessage, int statusCode, string claims, + Exception innerException) + : this( + errorCode, errorMessage, statusCode, innerException) + { + Claims = claims; + } + + /// + /// Gets the status code returned from http layer. This status code is either the HttpStatusCode in the inner + /// HttpRequestException response or + /// NavigateError Event Status Code in browser based flow (See + /// http://msdn.microsoft.com/en-us/library/bb268233(v=vs.85).aspx). + /// You can use this code for purposes such as implementing retry logic or error investigation. + /// + public int StatusCode { get; } = 0; + + /// + /// + /// + public string Claims { get; internal set; } + + /// + /// Raw response body received from the server. + /// + public string ResponseBody { get; internal set; } + + /// + /// Creates and returns a string representation of the current exception. + /// + /// A string representation of the current exception. + public override string ToString() + { + return base.ToString() + string.Format(CultureInfo.InvariantCulture, "\n\tStatusCode: {0}\n\tClaims: {1}", StatusCode, Claims); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta new file mode 100644 index 0000000..d2c680b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8cd474afd27c334a8896fdb5a8d9885 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs new file mode 100644 index 0000000..cc908c0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs @@ -0,0 +1,97 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client +{ + /// + /// This exception class is to inform developers that UI interaction is required for authentication to + /// succeed. + /// + public class MsalUiRequiredException : MsalServiceException + { + /// + /// Standard OAuth2 protocol error code. It indicates to the libray that the user needs to go the UI for + /// getting a new token. + /// + public static readonly string InvalidGrantError = "invalid_grant"; + + /// + /// No tokens were found matching the criteria. + /// + public static readonly string NoTokensFoundError = "no_tokens_found"; + + /// + /// This error code comes back from AcquireTokenSilent calls when null user is + /// passed into AcquireTokenSilent calls. + /// + public static readonly string UserNullError = "user_null"; + + /// + /// This error code comes back from AcquireTokenSilent calls when null token cache reference + /// is passed into the application constructor + /// + public static readonly string TokenCacheNullError = "token_cache_null"; + + /// + /// One of two conditions was encountered. + /// 1. The PromptBehavior.Never flag was passed and but the constraint could not be honored + /// because user interaction was required. + /// 2. An error occurred during a silent web authentication that prevented the authentication + /// flow from completing in a short enough time frame. + /// + public static readonly string NoPromptFailedError = "no_prompt_failed"; + + /// + /// Initializes a new instance of the exception class with a specified + /// error code and error message. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + public MsalUiRequiredException(string errorCode, string errorMessage):base(errorCode, errorMessage) + { + } + + /// + /// Initializes a new instance of the exception class with a specified + /// error code, error message and inner exception indicating the root cause. + /// + /// + /// The error code returned by the service or generated by client. This is the code you can rely on + /// for exception handling. + /// + /// The error message that explains the reason for the exception. + /// Represents the root cause of the exception. + public MsalUiRequiredException(string errorCode, string errorMessage, Exception innerException):base(errorCode, errorMessage, innerException) + { + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta new file mode 100644 index 0000000..245b5fd --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e1a3424339a1b246abe59ac961b4f76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta new file mode 100644 index 0000000..05af5ea --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ccbb989e5fe1172459881ba9f93fd7dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta new file mode 100644 index 0000000..b9b1d3a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc157d1bf480a4f409c281715eb265c9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs new file mode 100644 index 0000000..64bd980 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using Microsoft.Identity.Client.Internal; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text; + +namespace Microsoft.Identity.Client +{ + internal class CryptographyHelper + { + public static string CreateBase64UrlEncodedSha256Hash(string input) + { + if (string.IsNullOrEmpty(input)) + { + return null; + } + + using (SHA256 sha = SHA256.Create()) + { + UTF8Encoding encoding = new UTF8Encoding(); + return Base64UrlHelpers.Encode(sha.ComputeHash(encoding.GetBytes(input))); + } + } + + public static string GenerateCodeVerifier() + { + byte[] buffer = new byte[Constants.CodeVerifierByteSize]; + using (var randomSource = RandomNumberGenerator.Create()) + { + randomSource.GetBytes(buffer); + } + + return Base64UrlHelpers.Encode(buffer); + } + + public byte[] SignWithCertificate(string message, X509Certificate2 certificate) + { + using (var key = certificate.GetRSAPrivateKey()) + { + return key.SignData(Encoding.UTF8.GetBytes(message), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta new file mode 100644 index 0000000..ee2f0e6 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5b970a019ee617449b70f5ab7a6d47f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs new file mode 100644 index 0000000..96268ac --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs @@ -0,0 +1,65 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client +{ + internal class PlatformInformation : PlatformInformationBase + { + public PlatformInformation(RequestContext requestContext) : base(requestContext) + { + } + + public override string GetProductName() + { + return "MSAL.CoreCLR"; + } + + public override string GetEnvironmentVariable(string variable) + { + return null; + } + + public override string GetProcessorArchitecture() + { + return null; + } + + public override string GetOperatingSystem() + { + return System.Runtime.InteropServices.RuntimeInformation.OSDescription; + } + + public override string GetDeviceModel() + { + // Since MSAL .NET may be used on servers, for security reasons, we do not emit device type. + return null; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta new file mode 100644 index 0000000..5a73a5b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36dee80037890634cad3c0f83d08bc39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs new file mode 100644 index 0000000..0450be9 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs @@ -0,0 +1,41 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.Identity.Client.Internal.Interfaces; +using Microsoft.Identity.Client.Internal; + +namespace Microsoft.Identity.Client.Internal.UI +{ + internal class WebUIFactory : IWebUIFactory + { + public IWebUI CreateAuthenticationDialog(UIParent parent, RequestContext requestContext) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta new file mode 100644 index 0000000..e17f4ee --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf54b4a3b9ddc6d40a51437fa79b9f27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs new file mode 100644 index 0000000..58143ed --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs @@ -0,0 +1,380 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Internal.Interfaces; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.Requests; +using System.Collections.Generic; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client +{ + /// + /// Class to be used for native applications (Desktop/UWP/iOS/Android). + /// + public sealed partial class PublicClientApplication : ClientApplicationBase, IPublicClientApplication + { + /// + /// Consutructor of the application. It will use https://login.microsoftonline.com/common as the default authority. + /// + /// Client id of the application + public PublicClientApplication(string clientId) : this(clientId, DefaultAuthority) + { + } + + /// + /// Consutructor of the application. + /// + /// Client id of the application + /// Default authority to be used for the application + public PublicClientApplication(string clientId, string authority) + : base(clientId, authority, PlatformPlugin.PlatformInformation.GetDefaultRedirectUri(clientId), true) + { + UserTokenCache = new TokenCache() + { + ClientId = clientId + }; + } + + +#if WINRT +/// +/// +/// + public bool UseCorporateNetwork { get; set; } +#endif + +#if !ANDROID + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, null, + UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScope).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, + UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScopeHint).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync( + IEnumerable scopes, + IUser user) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authority, scopes, null, user, + UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScopeUser).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, + UIBehavior behavior, string extraQueryParameters) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, + behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehavior).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, + UIBehavior behavior, string extraQueryParameters) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authority, scopes, null, user, behavior, + extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehavior).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, + UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authorityInstance, scopes, extraScopesToConsent, + loginHint, behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehaviorAuthority).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, + UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authorityInstance, scopes, extraScopesToConsent, user, + behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehaviorAuthority).ConfigureAwait(false); + } +#endif + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, UIParent parent) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, null, + UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScope).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, UIParent parent) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, + UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHint).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync( + IEnumerable scopes, + IUser user, UIParent parent) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authority, scopes, null, user, + UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUser).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, + UIBehavior behavior, string extraQueryParameters, UIParent parent) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, + behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehavior).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, + UIBehavior behavior, string extraQueryParameters, UIParent parent) + { + Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authority, scopes, null, user, behavior, + extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehavior).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// Identifier of the user. Generally a UPN. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, + UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority, UIParent parent) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + return + await + AcquireTokenForLoginHintCommonAsync(authorityInstance, scopes, extraScopesToConsent, + loginHint, behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehaviorAuthority).ConfigureAwait(false); + } + + /// + /// Interactive request to acquire token. + /// + /// Array of scopes requested for resource + /// User object to enforce the same user to be authenticated in the web UI. + /// Enumeration to control UI behavior. + /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. + /// Array of scopes for which a developer can request consent upfront. + /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value + /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. + /// Authentication result containing token of the user + public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, + UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority, UIParent parent) + { + Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); + return + await + AcquireTokenForUserCommonAsync(authorityInstance, scopes, extraScopesToConsent, user, + behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehaviorAuthority).ConfigureAwait(false); + } + + + + internal IWebUI CreateWebAuthenticationDialog(UIParent parent, UIBehavior behavior, RequestContext requestContext) + { + //create instance of UIParent and assign useCorporateNetwork to UIParent + if (parent == null) + { + parent = new UIParent(); + } + +#if WINRT || DESKTOP + //hidden webview can be used in both WinRT and desktop applications. + parent.UseHiddenBrowser = behavior.Equals(UIBehavior.Never); +#if WINRT + parent.UseCorporateNetwork = UseCorporateNetwork; +#endif +#endif + + return PlatformPlugin.WebUIFactory.CreateAuthenticationDialog(parent, requestContext); + } + + private async Task AcquireTokenForLoginHintCommonAsync(Authority authority, IEnumerable scopes, + IEnumerable extraScopesToConsent, string loginHint, UIBehavior behavior, + string extraQueryParameters, UIParent parent, ApiEvent.ApiIds apiId) + { + var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); + requestParams.ExtraQueryParameters = extraQueryParameters; + var handler = + new InteractiveRequest(requestParams, extraScopesToConsent, loginHint, behavior, + CreateWebAuthenticationDialog(parent, behavior, requestParams.RequestContext)){ApiId = apiId}; + return await handler.RunAsync().ConfigureAwait(false); + } + + private async Task AcquireTokenForUserCommonAsync(Authority authority, IEnumerable scopes, + IEnumerable extraScopesToConsent, IUser user, UIBehavior behavior, string extraQueryParameters, UIParent parent, ApiEvent.ApiIds apiId) + { + + var requestParams = CreateRequestParameters(authority, scopes, user, UserTokenCache); + requestParams.ExtraQueryParameters = extraQueryParameters; + + var handler = + new InteractiveRequest(requestParams, extraScopesToConsent, behavior, + CreateWebAuthenticationDialog(parent, behavior, requestParams.RequestContext)){ApiId = apiId}; + return await handler.RunAsync().ConfigureAwait(false); + } + + internal override AuthenticationRequestParameters CreateRequestParameters(Authority authority, + IEnumerable scopes, IUser user, TokenCache cache) + { + AuthenticationRequestParameters parameters = base.CreateRequestParameters(authority, scopes, user, cache); + return parameters; + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta new file mode 100644 index 0000000..42ad553 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06a18977903d04243bcc9db801f1c76f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs new file mode 100644 index 0000000..931fb9d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs @@ -0,0 +1,209 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client +{ + /// + /// + /// + public class Telemetry + { + /// + /// + /// + /// + public delegate void Receiver(List> events); + + private Receiver _receiver = null; + + /// + /// + /// + /// + public void RegisterReceiver(Receiver r) + { + _receiver = r; + } + + private static readonly Telemetry Singleton = new Telemetry(); + + internal Telemetry(){} // This is an internal constructor to build isolated unit test instance + + /// + /// + /// + /// + public static Telemetry GetInstance() + { + return Singleton; + } + + /// + /// + /// + public bool TelemetryOnFailureOnly { get; set; } + + internal ConcurrentDictionary, EventBase> EventsInProgress = new ConcurrentDictionary, EventBase>(); + + internal ConcurrentDictionary> CompletedEvents = new ConcurrentDictionary>(); + + internal string GenerateNewRequestId() + { + return Guid.NewGuid().ToString(); + } + + internal void StartEvent(string requestId, EventBase eventToStart) + { + if (_receiver != null && requestId != null) + { + EventsInProgress[new Tuple(requestId, eventToStart[EventBase.EventNameKey])] = eventToStart; + } + } + + internal void StopEvent(string requestId, EventBase eventToStop) + { + if (_receiver == null || requestId == null) + { + return; + } + Tuple eventKey = new Tuple(requestId, eventToStop[EventBase.EventNameKey]); + + // Locate the same name event in the EventsInProgress map + EventBase eventStarted = null; + if (EventsInProgress.ContainsKey(eventKey)) + { + eventStarted = EventsInProgress[eventKey]; + } + + // If we did not get anything back from the dictionary, most likely its a bug that StopEvent + // was called without a corresponding StartEvent + if (null == eventStarted) + { + // Stop Event called without a corresponding start_event. + return; + } + + // Set execution time properties on the event + eventToStop.Stop(); + + if (!CompletedEvents.ContainsKey(requestId)) + { + // if this is the first event associated to this + // RequestId we need to initialize a new List to hold + // all of sibling events + List events = new List(); + events.Add(eventToStop); + CompletedEvents[requestId] = events; + } + else + { + // if this event shares a RequestId with other events + // just add it to the List + CompletedEvents[requestId].Add(eventToStop); + } + + // Mark this event as no longer in progress + EventBase dummy = null; // The TryRemove(...) next line requires an out parameter, even though we don't actually use it + EventsInProgress.TryRemove(eventKey, out dummy); + // We could use the following one-liner instead, but we believe it is less readable: + // ((IDictionary, EventBase>)EventsInProgress).Remove(eventKey); + } + + internal void Flush(string requestId) + { + if (_receiver == null) + { + return; + } + + // check for orphaned events... + List orphanedEvents = CollateOrphanedEvents(requestId); + // Add the OrphanedEvents to the completed EventList + if (!CompletedEvents.ContainsKey(requestId)) + { + // No completed Events returned for RequestId + return; + } + + CompletedEvents[requestId].AddRange(orphanedEvents); + + List eventsToFlush; + CompletedEvents.TryRemove(requestId, out eventsToFlush); + + if (TelemetryOnFailureOnly) + { + // iterate over Events, if the ApiEvent was successful, don't dispatch + bool shouldRemoveEvents = false; + + foreach (var anEvent in eventsToFlush) + { + var apiEvent = anEvent as ApiEvent; + if (apiEvent != null) + { + shouldRemoveEvents = apiEvent.WasSuccessful; + break; + } + } + + if (shouldRemoveEvents) + { + eventsToFlush.Clear(); + } + } + + if (eventsToFlush.Count > 0) + { + eventsToFlush.Insert(0, new DefaultEvent(ClientId)); + _receiver(eventsToFlush.Cast>().ToList()); + } + } + + private List CollateOrphanedEvents(String requestId) + { + var orphanedEvents = new List(); + foreach (var key in EventsInProgress.Keys) + { + if (key.Item1 == requestId) + { + // The orphaned event already contains its own start time, we simply collect it + EventBase orphan; + EventsInProgress.TryRemove(key, out orphan); + orphanedEvents.Add(orphan); + } + } + return orphanedEvents; + } + + internal string ClientId { get; set; } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta new file mode 100644 index 0000000..efa595d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce92cff5e49405a44820cf40f204bab9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs new file mode 100644 index 0000000..def51bc --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs @@ -0,0 +1,752 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Cache; +using Microsoft.Identity.Client.Internal.Instance; +using Microsoft.Identity.Client.Internal.OAuth2; +using Microsoft.Identity.Client.Internal.Requests; +using Microsoft.Identity.Client.Internal.Telemetry; + +namespace Microsoft.Identity.Client +{ + /// + /// Token cache class used by ConfidentialClientApplication and PublicClientApplication to store access and refresh tokens. + /// + public sealed class TokenCache + { + private const int DefaultExpirationBufferInMinutes = 5; + + internal readonly TelemetryTokenCacheAccessor TokenCacheAccessor = new TelemetryTokenCacheAccessor(); + + /// + /// Notification for certain token cache interactions during token acquisition. + /// + /// Arguments related to the cache item impacted + public delegate void TokenCacheNotification(TokenCacheNotificationArgs args); + + internal readonly object LockObject = new object(); + private volatile bool _hasStateChanged; + + internal string ClientId { get; set; } + + /// + /// Notification method called before any library method accesses the cache. + /// + internal TokenCacheNotification BeforeAccess { get; set; } + + /// + /// Notification method called before any library method writes to the cache. This notification can be used to reload + /// the cache state from a row in database and lock that row. That database row can then be unlocked in + /// AfterAccess notification. + /// + internal TokenCacheNotification BeforeWrite { get; set; } + + /// + /// Notification method called after any library method accesses the cache. + /// + internal TokenCacheNotification AfterAccess { get; set; } + + /// + /// Gets or sets the flag indicating whether cache state has changed. + /// MSAL methods set this flag after any change. + /// Caller application should reset the flag after serializing and persisting the state of the cache. + /// + public bool HasStateChanged + { + get { return _hasStateChanged; } + set { _hasStateChanged = value; } + } + + internal void OnAfterAccess(TokenCacheNotificationArgs args) + { + AfterAccess?.Invoke(args); + } + + internal void OnBeforeAccess(TokenCacheNotificationArgs args) + { + BeforeAccess?.Invoke(args); + } + + internal void OnBeforeWrite(TokenCacheNotificationArgs args) + { + HasStateChanged = true; + BeforeWrite?.Invoke(args); + } + + internal AccessTokenCacheItem SaveAccessAndRefreshToken(AuthenticationRequestParameters requestParams, + TokenResponse response) + { + lock (LockObject) + { + try + { + // create the access token cache item + AccessTokenCacheItem accessTokenCacheItem = + new AccessTokenCacheItem(requestParams.TenantUpdatedCanonicalAuthority, requestParams.ClientId, + response) + {UserAssertionHash = requestParams.UserAssertion?.AssertionHash}; + + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = accessTokenCacheItem.User + }; + + HasStateChanged = true; + OnBeforeAccess(args); + OnBeforeWrite(args); + + //delete all cache entries with intersecting scopes. + //this should not happen but we have this as a safe guard + //against multiple matches. + var msg = "Looking for scopes for the authority in the cache which intersect with " + + requestParams.Scope.AsSingleString(); + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + IList accessTokenItemList = new List(); + foreach (var accessTokenString in TokenCacheAccessor.GetAllAccessTokensAsString()) + { + AccessTokenCacheItem accessTokenItem = + JsonHelper.DeserializeFromJson(accessTokenString); + if (accessTokenItem.ClientId.Equals(ClientId) && + accessTokenItem.Authority.Equals(requestParams.TenantUpdatedCanonicalAuthority) && + accessTokenItem.ScopeSet.ScopeIntersects(accessTokenCacheItem.ScopeSet)) + { + msg = "Intersecting scopes found - " + accessTokenItem.Scope; + requestParams.RequestContext.Logger.Verbose(msg); + requestParams.RequestContext.Logger.VerbosePii(msg); + accessTokenItemList.Add(accessTokenItem); + } + } + + msg = "Intersecting scope entries count - " + accessTokenItemList.Count; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + + if (!requestParams.IsClientCredentialRequest) + { + //filter by identifer of the user instead + accessTokenItemList = + accessTokenItemList.Where( + item => item.GetUserIdentifier().Equals(accessTokenCacheItem.GetUserIdentifier())) + .ToList(); + msg = "Matching entries after filtering by user - " + accessTokenItemList.Count; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + } + + foreach (var cacheItem in accessTokenItemList) + { + TokenCacheAccessor.DeleteAccessToken(cacheItem.GetAccessTokenItemKey().ToString(), requestParams.RequestContext); + } + + TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), + JsonHelper.SerializeToJson(accessTokenCacheItem), requestParams.RequestContext); + + // if server returns the refresh token back, save it in the cache. + if (response.RefreshToken != null) + { + // create the refresh token cache item + RefreshTokenCacheItem refreshTokenCacheItem = new RefreshTokenCacheItem( + requestParams.Authority.Host, + requestParams.ClientId, + response); + msg = "Saving RT in cache..."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), + JsonHelper.SerializeToJson(refreshTokenCacheItem), requestParams.RequestContext); + } + + OnAfterAccess(args); + return accessTokenCacheItem; + } + finally + { + HasStateChanged = false; + } + } + } + + internal AccessTokenCacheItem FindAccessToken(AuthenticationRequestParameters requestParams) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheLookup) { TokenType = CacheEvent.TokenTypes.AT }; + Telemetry.GetInstance().StartEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); + try + { + return FindAccessTokenCommon(requestParams); + } + finally + { + Telemetry.GetInstance().StopEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); + } + } + + private AccessTokenCacheItem FindAccessTokenCommon(AuthenticationRequestParameters requestParams) + { + lock (LockObject) + { + string msg = "Looking up access token in the cache.."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + AccessTokenCacheItem accessTokenCacheItem = null; + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = requestParams.User + }; + + OnBeforeAccess(args); + //filtered by client id. + ICollection tokenCacheItems = GetAllAccessTokensForClient(requestParams.RequestContext); + OnAfterAccess(args); + + // this is OBO flow. match the cache entry with assertion hash, + // Authority, ScopeSet and client Id. + if (requestParams.UserAssertion != null) + { + msg = "Filtering by user assertion..."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + tokenCacheItems = + tokenCacheItems.Where( + item => + !string.IsNullOrEmpty(item.UserAssertionHash) && + item.UserAssertionHash.Equals(requestParams.UserAssertion.AssertionHash)) + .ToList(); + } + else + { + if (!requestParams.IsClientCredentialRequest) + { + msg = "Filtering by user identifier..."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + //filter by identifier of the user instead + tokenCacheItems = + tokenCacheItems + .Where(item => item.GetUserIdentifier().Equals(requestParams.User?.Identifier)) + .ToList(); + } + } + + //no match found after initial filtering + if (!tokenCacheItems.Any()) + { + msg = "No matching entry found for user or assertion"; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + return null; + } + + msg = "Matching entry count -" + tokenCacheItems.Count; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + + IEnumerable filteredItems = + tokenCacheItems.Where( + item => + item.ScopeSet.ScopeContains(requestParams.Scope)) + .ToList(); + + msg = "Matching entry count after filtering by scopes - " + filteredItems.Count(); + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + //no authority passed + if (requestParams.Authority == null) + { + msg = "No authority provided.."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + //if only one cached token found + if (filteredItems.Count() == 1) + { + accessTokenCacheItem = filteredItems.First(); + requestParams.Authority = + Authority.CreateAuthority(accessTokenCacheItem.Authority, requestParams.ValidateAuthority); + + msg = "1 matching entry found.Authority may be used for refreshing access token."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + } + else if (filteredItems.Count() > 1) + { + msg = "Multiple authorities found for same client_id, user and scopes"; + requestParams.RequestContext.Logger.Error(msg); + requestParams.RequestContext.Logger.ErrorPii(msg + " :- " + filteredItems + .Select(tci => tci.Authority) + .AsSingleString()); + throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, + MsalErrorMessage.MultipleTokensMatched); + } + else + { + msg = "No tokens found for matching client_id, user and scopes."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + + msg = "Check if the tokens are for the same authority for given client_id and user."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + //no match found. check if there was a single authority used + IEnumerable authorityList = tokenCacheItems.Select(tci => tci.Authority).Distinct(); + if (authorityList.Count() > 1) + { + msg = "Multiple authorities found for same client_id and user."; + requestParams.RequestContext.Logger.Error(msg); + requestParams.RequestContext.Logger.ErrorPii(msg + " :- " + authorityList.AsSingleString()); + + throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, + "Multiple authorities found in the cache. Pass in authority in the API overload."); + } + + msg = "Distinct Authority found. Use it for refresh token grant call"; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + requestParams.Authority = Authority.CreateAuthority(authorityList.First(), requestParams.ValidateAuthority); + } + } + else + { + msg = "Authority provided.."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + //authority was passed in the API + filteredItems = + filteredItems.Where( + item => + item.Authority.Equals(requestParams.Authority.CanonicalAuthority)) + .ToList(); + + //no match + if (!filteredItems.Any()) + { + msg = "No tokens found for matching authority, client_id, user and scopes."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + return null; + } + + //if only one cached token found + if (filteredItems.Count() == 1) + { + accessTokenCacheItem = filteredItems.First(); + } + else + { + msg = "Multiple tokens found for matching authority, client_id, user and scopes."; + requestParams.RequestContext.Logger.Error(msg); + requestParams.RequestContext.Logger.ErrorPii(msg); + + throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, + MsalErrorMessage.MultipleTokensMatched); + } + } + + if (accessTokenCacheItem != null && accessTokenCacheItem.ExpiresOn > + DateTime.UtcNow + TimeSpan.FromMinutes(DefaultExpirationBufferInMinutes)) + { + msg = "Access token is not expired. Returning the found cache entry.."; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + return accessTokenCacheItem; + } + + if (accessTokenCacheItem != null) + { + msg = "Access token has expired or about to expire. Current time (" + DateTime.UtcNow + + ") - Expiration Time (" + accessTokenCacheItem.ExpiresOn + ")"; + requestParams.RequestContext.Logger.Info(msg); + requestParams.RequestContext.Logger.InfoPii(msg); + } + + return null; + } + } + + internal RefreshTokenCacheItem FindRefreshToken(AuthenticationRequestParameters requestParams) + { + var cacheEvent = new CacheEvent(CacheEvent.TokenCacheLookup) { TokenType = CacheEvent.TokenTypes.RT }; + Telemetry.GetInstance().StartEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); + try + { + return FindRefreshTokenCommon(requestParams); + } + finally + { + Telemetry.GetInstance().StopEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); + } + } + + private RefreshTokenCacheItem FindRefreshTokenCommon(AuthenticationRequestParameters requestParam) + { + lock (LockObject) + { + var msg = "Looking up refresh token in the cache.."; + requestParam.RequestContext.Logger.Info(msg); + requestParam.RequestContext.Logger.InfoPii(msg); + if (requestParam.Authority == null) + { + return null; + } + + RefreshTokenCacheKey key = new RefreshTokenCacheKey( + requestParam.Authority.Host, requestParam.ClientId, + requestParam.User?.Identifier); + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = requestParam.User + }; + + OnBeforeAccess(args); + RefreshTokenCacheItem refreshTokenCacheItem = + JsonHelper.DeserializeFromJson( + TokenCacheAccessor.GetRefreshToken(key.ToString())); + OnAfterAccess(args); + + msg = "Refresh token found in the cache? - " + (refreshTokenCacheItem != null); + requestParam.RequestContext.Logger.Info(msg); + requestParam.RequestContext.Logger.InfoPii(msg); + return refreshTokenCacheItem; + } + } + + internal void DeleteRefreshToken(RefreshTokenCacheItem refreshTokenCacheItem) + { + lock (LockObject) + { + try + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = refreshTokenCacheItem.User + }; + + OnBeforeAccess(args); + OnBeforeWrite(args); + TokenCacheAccessor.DeleteRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString()); + OnAfterAccess(args); + } + finally + { + HasStateChanged = false; + } + } + } + + internal void DeleteAccessToken(AccessTokenCacheItem accessTokenCacheItem) + { + lock (LockObject) + { + try + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = accessTokenCacheItem.User + }; + + OnBeforeAccess(args); + OnBeforeWrite(args); + TokenCacheAccessor.DeleteAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString()); + OnAfterAccess(args); + } + finally + { + HasStateChanged = false; + } + } + } + + internal ICollection GetUsers(string environment, RequestContext requestContext) + { + lock (LockObject) + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = null + }; + + OnBeforeAccess(args); + ICollection tokenCacheItems = GetAllRefreshTokensForClient(requestContext); + OnAfterAccess(args); + + IDictionary allUsers = new Dictionary(); + foreach (RefreshTokenCacheItem item in tokenCacheItems) + { + if (environment.Equals( + item.Environment, StringComparison.OrdinalIgnoreCase)) + { + User user = new User(item.User); + allUsers[item.GetUserIdentifier()] = user; + } + } + + return allUsers.Values; + } + } + + internal ICollection GetAllRefreshTokensForClient(RequestContext requestContext) + { + lock (LockObject) + { + ICollection allRefreshTokens = new List(); + foreach (var refreshTokenString in TokenCacheAccessor.GetAllRefreshTokensAsString()) + { + RefreshTokenCacheItem refreshTokenCacheItem = + JsonHelper.DeserializeFromJson(refreshTokenString); + if (refreshTokenCacheItem.ClientId.Equals(ClientId)) + { + allRefreshTokens.Add(refreshTokenCacheItem); + } + } + + return allRefreshTokens; + } + } + + internal ICollection GetAllAccessTokensForClient(RequestContext requestContext) + { + lock (LockObject) + { + ICollection allAccessTokens = new List(); + foreach (var accessTokenString in TokenCacheAccessor.GetAllAccessTokensAsString()) + { + AccessTokenCacheItem accessTokenCacheItem = + JsonHelper.DeserializeFromJson(accessTokenString); + if (accessTokenCacheItem.ClientId.Equals(ClientId)) + { + allAccessTokens.Add(accessTokenCacheItem); + } + } + + return allAccessTokens; + } + } + + internal void Remove(IUser user, RequestContext requestContext) + { + lock (LockObject) + { + var msg = "Removing user from cache.."; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + + try + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = null + }; + + OnBeforeAccess(args); + OnBeforeWrite(args); + IList allRefreshTokens = GetAllRefreshTokensForClient(requestContext) + .Where(item => item.GetUserIdentifier().Equals(user.Identifier)) + .ToList(); + foreach (RefreshTokenCacheItem refreshTokenCacheItem in allRefreshTokens) + { + TokenCacheAccessor.DeleteRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), requestContext); + } + + msg = "Deleted refresh token count - " + allRefreshTokens.Count; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + IList allAccessTokens = GetAllAccessTokensForClient(requestContext) + .Where(item => item.GetUserIdentifier().Equals(user.Identifier)) + .ToList(); + + foreach (AccessTokenCacheItem accessTokenCacheItem in allAccessTokens) + { + TokenCacheAccessor.DeleteAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), requestContext); + } + + msg = "Deleted access token count - " + allAccessTokens.Count; + requestContext.Logger.Info(msg); + requestContext.Logger.InfoPii(msg); + OnAfterAccess(args); + } + finally + { + HasStateChanged = false; + } + } + } + + internal ICollection GetAllAccessTokenCacheItems(RequestContext requestContext) + { + // this method is called by serialize and does not require + // delegates because serialize itself is called from delegates + lock (LockObject) + { + ICollection allTokens = + TokenCacheAccessor.GetAllAccessTokensAsString(); + return allTokens; + } + } + + internal ICollection GetAllRefreshTokenCacheItems(RequestContext requestContext) + { + // this method is called by serialize and does not require + // delegates because serialize itself is called from delegates + lock (LockObject) + { + ICollection allTokens = + TokenCacheAccessor.GetAllRefreshTokensAsString(); + return allTokens; + } + } + + internal void AddAccessTokenCacheItem(AccessTokenCacheItem accessTokenCacheItem) + { + // this method is called by serialize and does not require + // delegates because serialize itself is called from delegates + lock (LockObject) + { + TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), + JsonHelper.SerializeToJson(accessTokenCacheItem)); + } + } + + internal void AddRefreshTokenCacheItem(RefreshTokenCacheItem refreshTokenCacheItem) + { + // this method is called by serialize and does not require + // delegates because serialize itself is called from delegates + lock (LockObject) + { + TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), + JsonHelper.SerializeToJson(refreshTokenCacheItem)); + } + } + + internal void ClearCache() + { + lock (LockObject) + { + try + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = null + }; + + OnBeforeAccess(args); + OnBeforeWrite(args); + + TokenCacheAccessor.Clear(); + + OnAfterAccess(args); + } + finally + { + HasStateChanged = false; + } + } + } + + /// + /// Only used by dev test apps + /// + /// + internal void SaveAccesTokenCacheItem(AccessTokenCacheItem accessTokenCacheItem) + { + lock (LockObject) + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = accessTokenCacheItem.User + }; + + try + { + HasStateChanged = true; + OnBeforeAccess(args); + OnBeforeWrite(args); + + TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), + JsonHelper.SerializeToJson(accessTokenCacheItem)); + } + finally + { + OnAfterAccess(args); + HasStateChanged = false; + } + } + } + + /// + /// Only used by dev test apps + /// + /// + internal void SaveRefreshTokenCacheItem(RefreshTokenCacheItem refreshTokenCacheItem) + { + lock (LockObject) + { + TokenCacheNotificationArgs args = new TokenCacheNotificationArgs + { + TokenCache = this, + ClientId = ClientId, + User = refreshTokenCacheItem.User + }; + + try + { + HasStateChanged = true; + OnBeforeAccess(args); + OnBeforeWrite(args); + + TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), + JsonHelper.SerializeToJson(refreshTokenCacheItem)); + } + finally + { + OnAfterAccess(args); + HasStateChanged = false; + } + } + } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta new file mode 100644 index 0000000..edc5e80 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6440d76bea7533a488c9efa9f0771d4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs new file mode 100644 index 0000000..f1586dd --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Identity.Client +{ + /// + /// Contains parameters used by the MSAL call accessing the cache. + /// + public sealed class TokenCacheNotificationArgs + { + /// + /// Gets the TokenCache + /// + public TokenCache TokenCache { get; internal set; } + + /// + /// Gets the ClientId. + /// + public string ClientId { get; internal set; } + + /// + /// Gets the user object. + /// + public IUser User { get; internal set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta new file mode 100644 index 0000000..fc75c62 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07824183ca3a9bb4a8d1f140b647055c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs new file mode 100644 index 0000000..38ac2e6 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Identity.Client +{ + /// + /// Indicates how AcquireToken should prompt the user. + /// + public partial struct UIBehavior + { + /// + /// AcquireToken will send prompt=select_account to authorize endpoint + /// and would show a list of users from which one can be selected for + /// authentication. + /// + public static readonly UIBehavior SelectAccount = new UIBehavior("select_account"); + + /// + /// The user will be prompted for credentials by the service. It is achieved + /// by sending prompt=login to the service. + /// + public static readonly UIBehavior ForceLogin = new UIBehavior("login"); + + /// + /// The user will be prompted to consent even if consent was granted before. It is achieved + /// by sending prompt=consent to the service. + /// + public static readonly UIBehavior Consent = new UIBehavior("consent"); + + +#if NET45 || WINRT + /// + /// Only available on .NET platform. AcquireToken will send prompt=attempt_none to + /// authorize endpoint and the library uses a hidden webview to authenticate the user. + /// + public static readonly UIBehavior Never = new UIBehavior("attempt_none"); +#endif + + internal string PromptValue { get; } + + private UIBehavior(string promptValue) + { + PromptValue = promptValue; + } + + /// + /// Equals method override to compare UIBehavior structs + /// + /// object to compare against + /// true if object are equal. + public override bool Equals(object obj) + { + return obj is UIBehavior && this == (UIBehavior)obj; + } + + /// + /// Override to compute hashcode + /// + /// hash code of the PromptValue + public override int GetHashCode() + { + return PromptValue.GetHashCode(); + } + + /// + /// operator overload to equality check + /// + /// first value + /// second value + /// true if the object are equal + public static bool operator ==(UIBehavior x, UIBehavior y) + { + return x.PromptValue == y.PromptValue; + } + + /// + /// operator overload to equality check + /// + /// first value + /// second value + /// true if the object are not equal + public static bool operator !=(UIBehavior x, UIBehavior y) + { + return !(x == y); + } + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta new file mode 100644 index 0000000..0fd8853 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22bd2dcd5d490ec4c8b6ffa2912f4d78 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs new file mode 100644 index 0000000..094f46f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs @@ -0,0 +1,88 @@ +//---------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +#if ANDROID +using System; +using Android.App; +#endif + + +namespace Microsoft.Identity.Client +{ + /// + /// + /// + public sealed class UIParent + { + /// + /// Default constructor. + /// + public UIParent() + { + } + +#if ANDROID + internal Activity Activity { get; set; } + + /// + /// Initializes an instance for a provided activity. + /// + /// parent activity for the call. REQUIRED. + public UIParent(Activity activity) + { + if(activity == null) + { + throw new ArgumentException("passed in activity is null", nameof(activity)); + } + + Activity = activity; + } +#endif + +#if DESKTOP || WINRT + //hidden webview can be used in both WinRT and desktop applications. + internal bool UseHiddenBrowser { get; set; } + +#if WINRT + internal bool UseCorporateNetwork { get; set; } +#endif + +#if DESKTOP + internal object OwnerWindow { get; set; } + + /// + /// Initializes an instance for a provided parent window. + /// + /// Parent window object reference. OPTIONAL. + public UIParent(object ownerWindow) + { + OwnerWindow = ownerWindow; + } +#endif +#endif + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta new file mode 100644 index 0000000..6e40ff4 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba9caa8db412a4c4c83ed9f74c8cff9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs new file mode 100644 index 0000000..7b93030 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs @@ -0,0 +1,79 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; + +namespace Microsoft.Identity.Client +{ + /// + /// Contains information of a single user. This information is used for token cache lookup and enforcing the user session on STS authorize endpont. + /// + internal sealed class User: IUser + { + public User() + { + } + + internal User(User other) + { + DisplayableId = other.DisplayableId; + Identifier = other.Identifier; + Name = other.Name; + IdentityProvider = other.IdentityProvider; + } + + public User(string identifier, string displayableId, string name, string identityProvider) + { + if (string.IsNullOrWhiteSpace(identifier)) + { + throw new ArgumentNullException(nameof(identifier)); + } + + DisplayableId = displayableId; + Name = name; + IdentityProvider = identityProvider; + Identifier = identifier; + } + + /// + /// Gets a displayable value in UserPrincipalName (UPN) format. The value can be null. + /// + public string DisplayableId { get; internal set; } + + /// + /// Gets given name of the user if provided by the service. If not, the value is null. + /// + public string Name { get; internal set; } + + /// + /// Gets identity provider if returned by the service. If not, the value is null. + /// + public string IdentityProvider { get; internal set; } + + public string Identifier { get; internal set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta new file mode 100644 index 0000000..694a32e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92fb77610f826264bb5a20d6ccfcd9f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs new file mode 100644 index 0000000..138ad51 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.OAuth2; + +namespace Microsoft.Identity.Client +{ + /// + /// Credential type containing an assertion representing user credential. + /// + public sealed class UserAssertion + { + /// + /// Constructor to create the object with an assertion. This constructor can be used for On Behalf Of flow which + /// assumes the + /// assertion is a JWT token. For other flows, the other construction with assertionType must be used. + /// + /// Assertion representing the user. + public UserAssertion(string assertion) : this(assertion, OAuth2GrantType.JwtBearer) + { + } + + /// + /// Constructor to create credential with assertion and assertionType + /// + /// Assertion representing the user. + /// Type of the assertion representing the user. + public UserAssertion(string assertion, string assertionType) + { + if (string.IsNullOrWhiteSpace(assertion)) + { + throw new ArgumentNullException(nameof(assertion)); + } + + if (string.IsNullOrWhiteSpace(assertionType)) + { + throw new ArgumentNullException(nameof(assertionType)); + } + + AssertionType = assertionType; + Assertion = assertion; + AssertionHash = + CryptographyHelper.CreateBase64UrlEncodedSha256Hash(Assertion); + } + + /// + /// Gets the assertion. + /// + public string Assertion { get; private set; } + + /// + /// Gets the assertion type. + /// + public string AssertionType { get; private set; } + + internal string AssertionHash { get; set; } + } +} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta new file mode 100644 index 0000000..e85a53d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21bbc1b8b9aee85449d2d9030fb75720 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs new file mode 100644 index 0000000..89f8a1e --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs @@ -0,0 +1,26 @@ +using Microsoft.Identity.Client; +using System.Collections.Generic; +using UnityEngine; + +public class StartupScript + : MonoBehaviour +{ + // Use this for initialization + void Start() + { + var clientId = ""; + var scopes = new List() + { + "User.Read", + }; + + var publicClientApplication = new PublicClientApplication(clientId); + var authenticationResult = publicClientApplication.AcquireTokenAsync(scopes).Result; + } + + // Update is called once per frame + void Update() + { + + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs.meta new file mode 100644 index 0000000..60f5a64 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3ed56f1e009a384f9cc7d196b9e8043 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/AudioManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..4f31e74 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/ClusterInputManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/DynamicsManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..78992f0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/EditorBuildSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..ea88784 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/Scenes/SampleScene.unity + guid: 99c9720ab356a0642a771bea13969a05 + m_configObjects: {} diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/EditorSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..29dea52 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/GraphicsSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..74d7b53 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,61 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/InputManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/NavMeshAreas.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/NetworkManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/NetworkManager.asset new file mode 100644 index 0000000..5dc6a83 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/Physics2DSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..132ee6b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_ChangeStopsCallbacks: 0 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/PresetManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..820e662 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/PresetManager.asset @@ -0,0 +1,27 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: + - type: + m_NativeTypeID: 108 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + defaultPresets: + - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea, + type: 2} + - type: + m_NativeTypeID: 1020 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + defaultPresets: + - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6, + type: 2} + - type: + m_NativeTypeID: 1006 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + defaultPresets: + - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9, + type: 2} diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..ca031e0 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,671 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 15 + productGUID: 9773106766118e7429aa8131c4a1b47d + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: TestingMsal + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + n3dsDisableStereoscopicView: 0 + n3dsEnableSharedListOpt: 1 + n3dsEnableVSync: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + videoMemoryForVertexBuffers: 0 + psp2PowerMode: 0 + psp2AcquireBGM: 1 + vulkanEnableSetSRGBWrite: 0 + vulkanUseSWCommandBuffers: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + enable360StereoCapture: 0 + protectGraphicsMemory: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 8.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + appleEnableProMotion: 0 + vulkanEditorSupport: 0 + clonedFromGUID: 0ea352821057f29478bc5a4fd7d4e8e1 + templatePackageId: com.unity.3d@1.0.1 + templateDefaultScene: Assets/Scenes/SampleScene.unity + AndroidTargetArchitectures: 5 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 0b00000015000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 0 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + psp2Splashimage: {fileID: 0} + psp2NPTrophyPackPath: + psp2NPSupportGBMorGJP: 0 + psp2NPAgeRating: 12 + psp2NPTitleDatPath: + psp2NPCommsID: + psp2NPCommunicationsID: + psp2NPCommsPassphrase: + psp2NPCommsSig: + psp2ParamSfxPath: + psp2ManualPath: + psp2LiveAreaGatePath: + psp2LiveAreaBackroundPath: + psp2LiveAreaPath: + psp2LiveAreaTrialPath: + psp2PatchChangeInfoPath: + psp2PatchOriginalPackage: + psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui + psp2KeystoneFile: + psp2MemoryExpansionMode: 0 + psp2DRMType: 0 + psp2StorageType: 0 + psp2MediaCapacity: 0 + psp2DLCConfigPath: + psp2ThumbnailPath: + psp2BackgroundPath: + psp2SoundPath: + psp2TrophyCommId: + psp2TrophyPackagePath: + psp2PackagedResourcesPath: + psp2SaveDataQuota: 10240 + psp2ParentalLevel: 1 + psp2ShortTitle: Not Set + psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF + psp2Category: 0 + psp2MasterVersion: 01.00 + psp2AppVersion: 01.00 + psp2TVBootMode: 0 + psp2EnterButtonAssignment: 2 + psp2TVDisableEmu: 0 + psp2AllowTwitterDialog: 1 + psp2Upgradable: 0 + psp2HealthWarning: 0 + psp2UseLibLocation: 0 + psp2InfoBarOnStartup: 0 + psp2InfoBarColor: 0 + psp2ScriptOptimizationLevel: 0 + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 1 + scriptingDefineSymbols: + 1: UNITY_POST_PROCESSING_STACK_V2 + 4: UNITY_POST_PROCESSING_STACK_V2 + 7: UNITY_POST_PROCESSING_STACK_V2 + 13: UNITY_POST_PROCESSING_STACK_V2 + 17: UNITY_POST_PROCESSING_STACK_V2 + 18: UNITY_POST_PROCESSING_STACK_V2 + 19: UNITY_POST_PROCESSING_STACK_V2 + 21: UNITY_POST_PROCESSING_STACK_V2 + 23: UNITY_POST_PROCESSING_STACK_V2 + 24: UNITY_POST_PROCESSING_STACK_V2 + 25: UNITY_POST_PROCESSING_STACK_V2 + 26: UNITY_POST_PROCESSING_STACK_V2 + 27: UNITY_POST_PROCESSING_STACK_V2 + platformArchitecture: {} + scriptingBackend: + Standalone: 1 + il2cppCompilerConfiguration: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + apiCompatibilityLevelPerPlatform: + Standalone: 6 + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_3D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_3D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + n3dsUseExtSaveData: 0 + n3dsCompressStaticMem: 1 + n3dsExtSaveDataNumber: 0x12345 + n3dsStackSize: 131072 + n3dsTargetPlatform: 2 + n3dsRegion: 7 + n3dsMediaSize: 0 + n3dsLogoStyle: 3 + n3dsTitle: GameName + n3dsProductCode: + n3dsApplicationId: 0xFF3FF + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: + UNet: 1 + facebookSdkVersion: 7.9.4 + apiCompatibilityLevel: 3 + cloudProjectId: 6db6be9b-81a5-4417-9e52-b01836d61bb7 + projectName: TestingMsal + organizationId: justin-wendlandt + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectVersion.txt b/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..5d90673 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2018.2.0x-ImprovedPrefabs diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/QualitySettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..b9320b3 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/QualitySettings.asset @@ -0,0 +1,190 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 4 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 2 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 4 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 4 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/TagManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..17cb803 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - PostProcessing + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/TimeManager.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..06bcc6d --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.1 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/Standalone-Samples/Unity-Identity/ProjectSettings/UnityConnectSettings.asset b/Standalone-Samples/Unity-Identity/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..f327fe1 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + m_Enabled: 0 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes + m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate + m_Enabled: 0 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 1 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/Standalone-Samples/Unity-Identity/TestingMsal.sln b/Standalone-Samples/Unity-Identity/TestingMsal.sln new file mode 100644 index 0000000..859560f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/TestingMsal.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestingMsal", "Assembly-CSharp.csproj", "{0037223C-A948-414E-4BF6-F39E8B8A73BD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From 576fc24a4ccafd06fa5a2061133f0a737b80af65 Mon Sep 17 00:00:00 2001 From: Justin Wendlandt Date: Mon, 23 Jul 2018 21:51:44 -0700 Subject: [PATCH 2/5] Moving files around. --- .../Assembly-CSharp-Editor.csproj | 725 ++++++++++++++++++ .../Unity-Identity/Assembly-CSharp.csproj | 187 ++--- .../Assets/Plugins/Newtonsoft.Json.dll | Bin 0 -> 655872 bytes .../Assets/Plugins/Newtonsoft.Json.dll.meta | 118 +++ .../Assets/Scenes/SampleScene.unity | 2 + ...AL.meta => Microsoft.Identity.Client.meta} | 2 +- .../AuthenticationResult.cs | 0 .../AuthenticationResult.cs.meta | 0 .../ClientApplicationBase.cs | 23 +- .../ClientApplicationBase.cs.meta | 0 .../Features.meta | 2 +- .../Features/ConfidentialClient.meta | 2 +- .../ClientAssertionCertificate.cs | 0 .../ClientAssertionCertificate.cs.meta | 0 .../ConfidentialClient/ClientCredential.cs | 0 .../ClientCredential.cs.meta | 0 .../ConfidentialClientApplication.cs | 0 .../ConfidentialClientApplication.cs.meta | 0 .../IConfidentialClientApplication.cs | 0 .../IConfidentialClientApplication.cs.meta | 0 .../ConfidentialClient/JsonWebToken.cs | 0 .../ConfidentialClient/JsonWebToken.cs.meta | 0 .../Features/EventSource.meta | 2 +- .../Features/EventSource/MsalEventSource.cs | 0 .../EventSource/MsalEventSource.cs.meta | 0 .../Features/EventSource/PlatformLogger.cs | 0 .../EventSource/PlatformLogger.cs.meta | 0 .../Features/PublicClient.meta | 2 +- .../PublicClient/PublicClientApplication.cs | 0 .../PublicClientApplication.cs.meta | 0 .../Features/TokenCache.meta | 2 +- .../Features/TokenCache/TokenCacheAccessor.cs | 0 .../TokenCache/TokenCacheAccessor.cs.meta | 0 .../TokenCache/TokenCacheExtensions.cs | 0 .../TokenCache/TokenCacheExtensions.cs.meta | 0 .../IClientApplicationBase.cs | 0 .../IClientApplicationBase.cs.meta | 0 .../IPublicClientApplication.cs | 0 .../IPublicClientApplication.cs.meta | 0 .../IUser.cs | 0 .../IUser.cs.meta | 0 .../Internal.meta | 2 +- .../Internal/AuthorizationResult.cs | 0 .../Internal/AuthorizationResult.cs.meta | 0 .../Internal/Base64UrlHelpers.cs | 0 .../Internal/Base64UrlHelpers.cs.meta | 0 .../Internal/Cache.meta | 2 +- .../Internal/Cache/AccessTokenCacheItem.cs | 0 .../Cache/AccessTokenCacheItem.cs.meta | 0 .../Internal/Cache/AccessTokenCacheKey.cs | 0 .../Cache/AccessTokenCacheKey.cs.meta | 0 .../Internal/Cache/BaseTokenCacheItem.cs | 0 .../Internal/Cache/BaseTokenCacheItem.cs.meta | 0 .../Internal/Cache/ITokenCacheAccessor.cs | 0 .../Cache/ITokenCacheAccessor.cs.meta | 0 .../Internal/Cache/RefreshTokenCacheItem.cs | 0 .../Cache/RefreshTokenCacheItem.cs.meta | 0 .../Internal/Cache/RefreshTokenCacheKey.cs | 0 .../Cache/RefreshTokenCacheKey.cs.meta | 0 .../Internal/Cache/TokenCacheKeyBase.cs | 0 .../Internal/Cache/TokenCacheKeyBase.cs.meta | 0 .../Internal/ClientInfo.cs | 0 .../Internal/ClientInfo.cs.meta | 0 .../Internal/Constants.cs | 0 .../Internal/Constants.cs.meta | 0 .../Internal/Extensions.cs | 0 .../Internal/Extensions.cs.meta | 0 .../Internal/Http.meta | 2 +- .../Internal/Http/HttpClientFactory.cs | 0 .../Internal/Http/HttpClientFactory.cs.meta | 0 .../Http/HttpMessageHandlerFactory.cs | 0 .../Http/HttpMessageHandlerFactory.cs.meta | 0 .../Internal/Http/HttpRequest.cs | 0 .../Internal/Http/HttpRequest.cs.meta | 0 .../Internal/Http/HttpResponse.cs | 0 .../Internal/Http/HttpResponse.cs.meta | 0 .../Internal/ILogger.cs | 0 .../Internal/ILogger.cs.meta | 0 .../Internal/IdToken.cs | 0 .../Internal/IdToken.cs.meta | 0 .../Internal/Instance.meta | 2 +- .../Internal/Instance/AadAuthority.cs | 0 .../Internal/Instance/AadAuthority.cs.meta | 0 .../Internal/Instance/AdfsAuthority.cs | 0 .../Internal/Instance/AdfsAuthority.cs.meta | 0 .../Instance/AdfsWebFingerResponse.cs | 0 .../Instance/AdfsWebFingerResponse.cs.meta | 0 .../Internal/Instance/Authority.cs | 0 .../Internal/Instance/Authority.cs.meta | 0 .../Internal/Instance/B2CAuthority.cs | 0 .../Internal/Instance/B2CAuthority.cs.meta | 0 .../Internal/Instance/DrsMetadataResponse.cs | 0 .../Instance/DrsMetadataResponse.cs.meta | 0 .../Instance/InstanceDiscoveryResponse.cs | 0 .../InstanceDiscoveryResponse.cs.meta | 0 .../Instance/TenantDiscoveryResponse.cs | 0 .../Instance/TenantDiscoveryResponse.cs.meta | 0 .../Internal/Interfaces.meta | 2 +- .../Internal/Interfaces/IWebUI.cs | 0 .../Internal/Interfaces/IWebUI.cs.meta | 0 .../Internal/Interfaces/IWebUIFactory.cs | 0 .../Internal/Interfaces/IWebUIFactory.cs.meta | 0 .../Internal/JsonHelper.cs | 0 .../Internal/JsonHelper.cs.meta | 0 .../Internal/MsalError.cs | 0 .../Internal/MsalError.cs.meta | 0 .../Internal/MsalHelpers.cs | 0 .../Internal/MsalHelpers.cs.meta | 0 .../Internal/MsalIdHelper.cs | 0 .../Internal/MsalIdHelper.cs.meta | 0 .../Internal/OAuth2.meta | 2 +- .../Internal/OAuth2/OAuth2Client.cs | 0 .../Internal/OAuth2/OAuth2Client.cs.meta | 0 .../Internal/OAuth2/OAuth2ResponseBase.cs | 0 .../OAuth2/OAuth2ResponseBase.cs.meta | 0 .../Internal/OAuth2/OAuthConstants.cs | 0 .../Internal/OAuth2/OAuthConstants.cs.meta | 0 .../Internal/OAuth2/TokenResponse.cs | 0 .../Internal/OAuth2/TokenResponse.cs.meta | 0 .../Internal/PlatformInformationBase.cs | 6 +- .../Internal/PlatformInformationBase.cs.meta | 0 .../Internal/PlatformPlugin.cs | 0 .../Internal/PlatformPlugin.cs.meta | 0 .../Internal/RequestContext.cs | 0 .../Internal/RequestContext.cs.meta | 0 .../Internal/Requests.meta | 2 +- .../AuthenticationRequestParameters.cs | 0 .../AuthenticationRequestParameters.cs.meta | 0 .../Requests/AuthorizationCodeRequest.cs | 0 .../Requests/AuthorizationCodeRequest.cs.meta | 0 .../Requests/ClientCredentialRequest.cs | 0 .../Requests/ClientCredentialRequest.cs.meta | 0 .../Internal/Requests/InteractiveRequest.cs | 0 .../Requests/InteractiveRequest.cs.meta | 0 .../Internal/Requests/OnBehalfOfRequest.cs | 0 .../Requests/OnBehalfOfRequest.cs.meta | 0 .../Internal/Requests/RequestBase.cs | 0 .../Internal/Requests/RequestBase.cs.meta | 0 .../Internal/Requests/SilentRequest.cs | 0 .../Internal/Requests/SilentRequest.cs.meta | 0 .../Internal/Telemetry.meta | 2 +- .../Internal/Telemetry/ApiEvent.cs | 0 .../Internal/Telemetry/ApiEvent.cs.meta | 0 .../Internal/Telemetry/CacheEvent.cs | 0 .../Internal/Telemetry/CacheEvent.cs.meta | 0 .../Internal/Telemetry/DefaultEvent.cs | 0 .../Internal/Telemetry/DefaultEvent.cs.meta | 0 .../Internal/Telemetry/Event.cs | 0 .../Internal/Telemetry/Event.cs.meta | 0 .../Internal/Telemetry/HttpEvent.cs | 0 .../Internal/Telemetry/HttpEvent.cs.meta | 0 .../Telemetry/TelemetryTokenCacheAccessor.cs | 0 .../TelemetryTokenCacheAccessor.cs.meta | 0 .../Internal/Telemetry/UiEvent.cs | 0 .../Internal/Telemetry/UiEvent.cs.meta | 0 .../Logger.cs | 0 .../Logger.cs.meta | 0 .../MsalClientException.cs | 0 .../MsalClientException.cs.meta | 0 .../MsalException.cs | 0 .../MsalException.cs.meta | 0 .../MsalServiceException.cs | 0 .../MsalServiceException.cs.meta | 0 .../MsalUiRequiredException.cs | 0 .../MsalUiRequiredException.cs.meta | 0 .../Platforms.meta | 2 +- .../Platforms/Unity.meta | 2 +- .../Platforms/Unity/CryptographyHelper.cs | 4 +- .../Unity/CryptographyHelper.cs.meta | 2 +- .../Platforms/Unity/PlatformInformation.cs | 5 +- .../Unity/PlatformInformation.cs.meta | 2 +- .../Platforms/Unity/UnityWebUI.cs | 20 + .../Platforms/Unity/UnityWebUI.cs.meta | 11 + .../Platforms/Unity/WebUIFactory.cs | 12 +- .../Platforms/Unity/WebUIFactory.cs.meta | 2 +- .../Microsoft.Identity.Client/Properties.meta | 8 + .../Properties/InternalsVisibleTo.cs | 14 + .../Properties/InternalsVisibleTo.cs.meta | 11 + .../Microsoft.Identity.Client.rd.xml | 33 + .../Microsoft.Identity.Client.rd.xml.meta | 7 + .../PublicClientApplication.cs | 0 .../PublicClientApplication.cs.meta | 0 .../Microsoft.Identity.Client/Resources.meta | 8 + .../Resources/AboutResources.txt | 50 ++ .../Resources/AboutResources.txt.meta | 7 + .../Resources/Values.meta | 8 + .../Resources/Values/Strings.xml | 5 + .../Resources/Values/Strings.xml.meta | 7 + .../Resources/layout.meta | 8 + .../layout/WebAuthenticationBroker.axml | 12 + .../layout/WebAuthenticationBroker.axml.meta | 7 + .../Telemetry.cs | 0 .../Telemetry.cs.meta | 0 .../TokenCache.cs | 0 .../TokenCache.cs.meta | 0 .../TokenCacheNotificationArgs.cs | 0 .../TokenCacheNotificationArgs.cs.meta | 0 .../UIBehavior.cs | 0 .../UIBehavior.cs.meta | 0 .../UIParent.cs | 0 .../UIParent.cs.meta | 0 .../User.cs | 0 .../User.cs.meta | 0 .../UserAssertion.cs | 0 .../UserAssertion.cs.meta | 0 .../Assets/Scripts/ServiceLocator.cs | 28 + .../Assets/Scripts/ServiceLocator.cs.meta | 11 + .../Assets/Scripts/StartupScript.cs | 18 +- .../Unity-Identity/Unity-Identity.sln | 20 + 209 files changed, 1280 insertions(+), 133 deletions(-) create mode 100644 Standalone-Samples/Unity-Identity/Assembly-CSharp-Editor.csproj create mode 100644 Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll create mode 100644 Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll.meta rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL.meta => Microsoft.Identity.Client.meta} (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/AuthenticationResult.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/AuthenticationResult.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/ClientApplicationBase.cs (95%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/ClientApplicationBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ClientAssertionCertificate.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ClientCredential.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ClientCredential.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ConfidentialClientApplication.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/IConfidentialClientApplication.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/JsonWebToken.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/ConfidentialClient/JsonWebToken.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/EventSource.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/EventSource/MsalEventSource.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/EventSource/MsalEventSource.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/EventSource/PlatformLogger.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/EventSource/PlatformLogger.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/PublicClient.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/PublicClient/PublicClientApplication.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/PublicClient/PublicClientApplication.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/TokenCache.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/TokenCache/TokenCacheAccessor.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/TokenCache/TokenCacheAccessor.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/TokenCache/TokenCacheExtensions.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Features/TokenCache/TokenCacheExtensions.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IClientApplicationBase.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IClientApplicationBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IPublicClientApplication.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IPublicClientApplication.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IUser.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/IUser.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/AuthorizationResult.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/AuthorizationResult.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Base64UrlHelpers.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Base64UrlHelpers.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/AccessTokenCacheItem.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/AccessTokenCacheItem.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/AccessTokenCacheKey.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/AccessTokenCacheKey.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/BaseTokenCacheItem.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/BaseTokenCacheItem.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/ITokenCacheAccessor.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/ITokenCacheAccessor.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/RefreshTokenCacheItem.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/RefreshTokenCacheItem.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/RefreshTokenCacheKey.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/RefreshTokenCacheKey.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/TokenCacheKeyBase.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Cache/TokenCacheKeyBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/ClientInfo.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/ClientInfo.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Constants.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Constants.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Extensions.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Extensions.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpClientFactory.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpClientFactory.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpMessageHandlerFactory.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpMessageHandlerFactory.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Http/HttpResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/ILogger.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/ILogger.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/IdToken.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/IdToken.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AadAuthority.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AadAuthority.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AdfsAuthority.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AdfsAuthority.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AdfsWebFingerResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/AdfsWebFingerResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/Authority.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/Authority.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/B2CAuthority.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/B2CAuthority.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/DrsMetadataResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/DrsMetadataResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/InstanceDiscoveryResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/InstanceDiscoveryResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/TenantDiscoveryResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Instance/TenantDiscoveryResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Interfaces.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Interfaces/IWebUI.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Interfaces/IWebUI.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Interfaces/IWebUIFactory.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Interfaces/IWebUIFactory.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/JsonHelper.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/JsonHelper.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalError.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalError.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalHelpers.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalHelpers.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalIdHelper.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/MsalIdHelper.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuth2Client.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuth2Client.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuth2ResponseBase.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuth2ResponseBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuthConstants.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/OAuthConstants.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/TokenResponse.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/OAuth2/TokenResponse.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/PlatformInformationBase.cs (93%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/PlatformInformationBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/PlatformPlugin.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/PlatformPlugin.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/RequestContext.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/RequestContext.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/AuthenticationRequestParameters.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/AuthenticationRequestParameters.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/AuthorizationCodeRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/AuthorizationCodeRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/ClientCredentialRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/ClientCredentialRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/InteractiveRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/InteractiveRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/OnBehalfOfRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/OnBehalfOfRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/RequestBase.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/RequestBase.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/SilentRequest.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Requests/SilentRequest.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/ApiEvent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/ApiEvent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/CacheEvent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/CacheEvent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/DefaultEvent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/DefaultEvent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/Event.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/Event.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/HttpEvent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/HttpEvent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/TelemetryTokenCacheAccessor.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/UiEvent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Internal/Telemetry/UiEvent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Logger.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Logger.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalClientException.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalClientException.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalException.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalException.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalServiceException.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalServiceException.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalUiRequiredException.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/MsalUiRequiredException.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity.meta (77%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/CryptographyHelper.cs (99%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/CryptographyHelper.cs.meta (83%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/PlatformInformation.cs (98%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/PlatformInformation.cs.meta (83%) create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/WebUIFactory.cs (90%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Platforms/Unity/WebUIFactory.cs.meta (83%) create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/PublicClientApplication.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/PublicClientApplication.cs.meta (100%) create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Telemetry.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/Telemetry.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/TokenCache.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/TokenCache.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/TokenCacheNotificationArgs.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/TokenCacheNotificationArgs.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UIBehavior.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UIBehavior.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UIParent.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UIParent.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/User.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/User.cs.meta (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UserAssertion.cs (100%) rename Standalone-Samples/Unity-Identity/Assets/Scripts/{MSAL => Microsoft.Identity.Client}/UserAssertion.cs.meta (100%) create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta create mode 100644 Standalone-Samples/Unity-Identity/Unity-Identity.sln diff --git a/Standalone-Samples/Unity-Identity/Assembly-CSharp-Editor.csproj b/Standalone-Samples/Unity-Identity/Assembly-CSharp-Editor.csproj new file mode 100644 index 0000000..96ff441 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assembly-CSharp-Editor.csproj @@ -0,0 +1,725 @@ + + + + 6 + + + Debug + AnyCPU + 10.0.20506 + 2.0 + + {BC7F42D7-0D14-759D-EEAB-73C1A5592702} + Library + Properties + Assembly-CSharp-Editor + v4.7.1 + 512 + . + + + true + full + false + Temp\bin\Debug\ + DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_2_0;UNITY_2018_2;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;UNITY_ANALYTICS;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_TEXTURE_STREAMING;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE;UNITY_POST_PROCESSING_STACK_V2;ENABLE_MONO + prompt + 4 + 0169 + False + + + pdbonly + true + Temp\bin\Release\ + prompt + 4 + 0169 + False + + + true + true + false + false + false + + + {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Unity/VSTU + Editor:5 + StandaloneWindows64:19 + 2018.2.0x-ImprovedPrefabs + + + + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll + + + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEditor.dll + + + + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.TextMeshPro.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticlesLegacyModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpatialTrackingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/Unity.Locator.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/Editor/UnityEditor.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/Editor/UnityEditor.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/Editor/UnityEditor.TestRunner.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/UnityEngine.TestRunner.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/net35/unity-custom/nunit.framework.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/Editor/UnityEditor.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TreeEditor/Editor/UnityEditor.TreeEditor.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/Editor/UnityEditor.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/Editor/UnityEditor.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/Editor/UnityEditor.SpatialTracking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEditor.Graphs.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/AndroidPlayer/UnityEditor.Android.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/MetroSupport/UnityEditor.WSA.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/windowsstandalonesupport/UnityEditor.WindowsStandalone.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/MacStandaloneSupport/UnityEditor.OSXStandalone.Extensions.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.ads@2.0.8/Editor/UnityEditor.Advertisements.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/Editor/UnityEditor.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/Editor/UnityEditor.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll + + + C:/Program Files (x86)/Microsoft Visual Studio Tools for Unity/15.0/Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Assets/SimpleWebBrowser/Plugins/MessageLibrary.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Assets/SimpleWebBrowser/Plugins/x86_x64/SharedMemory.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll + + + + + {560AF659-E7F3-E280-76A2-B130C3C5C968} + Assembly-CSharp + + + + + + \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj index e010e9e..c7b9e5c 100644 --- a/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj +++ b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj @@ -9,7 +9,7 @@ 10.0.20506 2.0 - {0037223C-A948-414E-4BF6-F39E8B8A73BD} + {560AF659-E7F3-E280-76A2-B130C3C5C968} Library Properties Assembly-CSharp @@ -60,102 +60,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll - C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll - C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll - C:/Users/juswen/Downloads/Unity/TestingMsal/Library/ScriptAssemblies/Unity.TextMeshPro.dll + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/Unity.TextMeshPro.dll C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll @@ -361,6 +367,9 @@ C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/ref/2.0.0/netstandard.dll diff --git a/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll b/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..63b1a9965e2aaacbfb65d68a4cff7e9554c9163b GIT binary patch literal 655872 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

?S$yLDvY17zOjv;|HiUE{F2r;bb2hI<)huN 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%0Dbg5!2QR`o;}gt$aLLuLB1)j8ST|$xfR8C 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�i_mg!O&`#pZoQFdcdw$4F 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 @@ -231,7 +232,7 @@ internal virtual AuthenticationRequestParameters CreateRequestParameters(Authori { SliceParameters = SliceParameters, Authority = authority, - ClientId = ClientId, + ClientId = ClientId, TokenCache = cache, User = user, Scope = scopes.CreateSetFromEnumerable(), diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/ClientApplicationBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta index 2ac5535..4b62472 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9056496dc597f4849842fa16abab6463 +guid: 7d7b1f184e5dfe843a93ee6e3d0ae427 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta index 70ea9ec..68058ba 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 70e24b9bcc9390a4ba7f08d20eb062a1 +guid: 73c1eb1ad8f8d4f47bb5c0ce9d6394f8 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ClientCredential.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/ConfidentialClient/JsonWebToken.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta index 4f2bd53..b18da13 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 332af1b833a8db848b0aa4af906bdf93 +guid: 35efa734661209d488390191f4d33b2e folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/MsalEventSource.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/EventSource/PlatformLogger.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta index 55eddd8..b7a75b8 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ae6cb4ef844bc9b46b320747d7376ab4 +guid: 6dbcbfaf6cbdd574f9e598977e97b118 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/PublicClient/PublicClientApplication.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta index e008a2e..bdcf1f5 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d050d96e022f4d3478e4f34a8d4ae203 +guid: 9b090cd9b2db50a47a7ae0dcde7e099a folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheAccessor.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Features/TokenCache/TokenCacheExtensions.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IClientApplicationBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IPublicClientApplication.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/IUser.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta index 940a39b..3f6c6ea 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f28e821199708264782c242025140e67 +guid: 590cf9813e95eb74f9aa09c2eb4e73ee folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/AuthorizationResult.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Base64UrlHelpers.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta index 988125a..ec41e29 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f8f985ee5c770d54fae506579acef4ff +guid: a20fd9b49a977a444aecc63a5bc521e6 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheItem.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/AccessTokenCacheKey.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/BaseTokenCacheItem.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/ITokenCacheAccessor.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheItem.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/RefreshTokenCacheKey.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Cache/TokenCacheKeyBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ClientInfo.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Constants.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Extensions.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta index 871a754..175294b 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e5d2324a9f903bf4f93f080b3c998121 +guid: 86835f11e65c98a419f1ed93ac731350 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpClientFactory.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpMessageHandlerFactory.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Http/HttpResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/ILogger.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/IdToken.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta index 8435d34..45d90f9 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0758634a94e49dd4ea925e88e1383296 +guid: 32847ba824167b1468e3c15cbb573fdc folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AadAuthority.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsAuthority.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/AdfsWebFingerResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/Authority.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/B2CAuthority.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/DrsMetadataResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/InstanceDiscoveryResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Instance/TenantDiscoveryResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta index 44ef001..a24a683 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 70250363cbac48f4c93edf73cbac75c7 +guid: 0d3b45f3e6ccd8449baa6023e9d6f7e2 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUI.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Interfaces/IWebUIFactory.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/JsonHelper.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalError.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalHelpers.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/MsalIdHelper.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta index ea84f60..1c47a90 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: be415a15ae5a8bd4895c37c49b806038 +guid: a70ef007086b44447af760be8b2a93c6 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2Client.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuth2ResponseBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/OAuthConstants.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/OAuth2/TokenResponse.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs similarity index 93% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs index 80918bf..c92c19a 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs @@ -26,9 +26,7 @@ //------------------------------------------------------------------------------ using System; -using System.Reflection; using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; namespace Microsoft.Identity.Client.Internal { @@ -50,8 +48,8 @@ protected PlatformInformationBase(RequestContext requestContext) public virtual string GetAssemblyFileVersionAttribute() { - return - typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute().Version; + //return typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute().Version; + return "N/A"; } public virtual async Task IsUserLocalAsync(RequestContext requestContext) diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformInformationBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/PlatformPlugin.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/RequestContext.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta index f2ee793..e7e7bfc 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3eccb36c6aa89174dbba4d918a91108c +guid: a75e59c48a5a30e43bb68928fd7c6179 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthenticationRequestParameters.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/AuthorizationCodeRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/ClientCredentialRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/InteractiveRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/OnBehalfOfRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/RequestBase.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Requests/SilentRequest.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta index a3a65d4..40f4416 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 934fef8613a74304cb23290708437023 +guid: 7e9f8434bad8cf64b8688555924713ea folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/ApiEvent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/CacheEvent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/DefaultEvent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/Event.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/HttpEvent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Internal/Telemetry/UiEvent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Logger.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalClientException.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalException.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalServiceException.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/MsalUiRequiredException.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta index 05af5ea..801c83b 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ccbb989e5fe1172459881ba9f93fd7dc +guid: 25b08f028a366be4b8696b6d36643a02 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta index b9b1d3a..abe612b 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fc157d1bf480a4f409c281715eb265c9 +guid: c0a1b7ac4cc22b64288a352174fa1c6f folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs similarity index 99% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs index 64bd980..3497eb3 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs @@ -25,6 +25,7 @@ // //------------------------------------------------------------------------------ +#if UNITY_EDITOR using Microsoft.Identity.Client.Internal; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; @@ -67,4 +68,5 @@ public byte[] SignWithCertificate(string message, X509Certificate2 certificate) } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta similarity index 83% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta index ee2f0e6..114d27d 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/CryptographyHelper.cs.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a5b970a019ee617449b70f5ab7a6d47f +guid: ebad180b7ce78bf4b97090090bf0a6f5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs similarity index 98% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs index 96268ac..8257bff 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs @@ -25,7 +25,7 @@ // //------------------------------------------------------------------------------ -using System.Threading.Tasks; +#if UNITY_EDITOR using Microsoft.Identity.Client.Internal; namespace Microsoft.Identity.Client @@ -62,4 +62,5 @@ public override string GetDeviceModel() return null; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta similarity index 83% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta index 5a73a5b..07818b1 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/PlatformInformation.cs.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 36dee80037890634cad3c0f83d08bc39 +guid: 542b74d785c1fd54bb398b8084f83475 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs new file mode 100644 index 0000000..edbe3af --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs @@ -0,0 +1,20 @@ +#if UNITY_EDITOR +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.Internal.Interfaces; +using System; +using System.Threading.Tasks; + +namespace Assets.Scripts.MSAL.Platforms.Unity +{ + internal class UnityWebUI + : IWebUI + { + public RequestContext RequestContext { get; set; } + + public Task AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext) + { + throw new NotImplementedException(); + } + } +} +#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta new file mode 100644 index 0000000..1ba2579 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c435d0d8f9d78a44c8b779b27a717aad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs similarity index 90% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs index 0450be9..b8c09ca 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs @@ -25,17 +25,19 @@ // //------------------------------------------------------------------------------ -using System; +#if UNITY_EDITOR +using Assets.Scripts.MSAL.Platforms.Unity; using Microsoft.Identity.Client.Internal.Interfaces; -using Microsoft.Identity.Client.Internal; namespace Microsoft.Identity.Client.Internal.UI { - internal class WebUIFactory : IWebUIFactory + internal class WebUIFactory + : IWebUIFactory { public IWebUI CreateAuthenticationDialog(UIParent parent, RequestContext requestContext) { - throw new NotImplementedException(); + return new UnityWebUI(); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta similarity index 83% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta index e17f4ee..60dc56c 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Platforms/Unity/WebUIFactory.cs.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cf54b4a3b9ddc6d40a51437fa79b9f27 +guid: ebb9b8ab681801c42a37fa1267106be9 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta new file mode 100644 index 0000000..109328b --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b2bafeba7c24b7c41a60acbf3712e9f1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs new file mode 100644 index 0000000..fef8f59 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; + +// Allow this assembly to be serviced when run on desktop CLR +[assembly: AssemblyMetadata("Serviceable", "True")] + +[assembly: InternalsVisibleTo("XForms, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] +[assembly: InternalsVisibleTo("AutomationApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] +[assembly: InternalsVisibleTo("DesktopTestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] +[assembly: InternalsVisibleTo("Test.MSAL.NET.Unit, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta new file mode 100644 index 0000000..dcb3a37 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 411421f03058bf74eb3532cbd582710b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml new file mode 100644 index 0000000..462f7be --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta new file mode 100644 index 0000000..cbcb99c --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 703695d3c76fa5f449177800faee251c +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/PublicClientApplication.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta new file mode 100644 index 0000000..803f041 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66b849cf47d51ae4dbd3356fec82036f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt new file mode 100644 index 0000000..194ae28 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt @@ -0,0 +1,50 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.xml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable-hdpi/ + icon.png + + drawable-ldpi/ + icon.png + + drawable-mdpi/ + icon.png + + layout/ + main.xml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called +"Resource" that contains the tokens for each one of the resources included. For example, +for the above Resources layout, this is what the Resource class would expose: + +public class Resource { + public class drawable { + public const int icon = 0x123; + } + + public class layout { + public const int main = 0x456; + } + + public class strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main +to reference the layout/main.xml file, or Resource.strings.first_string to reference the first +string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta new file mode 100644 index 0000000..5c9afae --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9cdad3331fa45964ab9529b7198096db +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta new file mode 100644 index 0000000..16e5368 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ef36d6d15d17791409a4af9d5ed0c895 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml new file mode 100644 index 0000000..b9c880f --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml @@ -0,0 +1,5 @@ + + + + $projectname$ + \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta new file mode 100644 index 0000000..f5989e6 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d2d03d9f0588c70468b3c6060ca584ef +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta new file mode 100644 index 0000000..8850014 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4af410608141b404bb11b1c540a3f131 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml new file mode 100644 index 0000000..13aaba7 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta new file mode 100644 index 0000000..9433f1a --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c013c8a9ada3f9245b88ffe7d7bba0b2 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/Telemetry.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCache.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/TokenCacheNotificationArgs.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIBehavior.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UIParent.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/User.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta similarity index 100% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/MSAL/UserAssertion.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs new file mode 100644 index 0000000..3a06c97 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace Assets.Scripts +{ + public static class ServiceLocator + { + private static IDictionary InternalServices = new Dictionary(); + + public static void RegisterService(Action> registrationCallback) + { + registrationCallback(InternalServices); + } + + public static T GetService() + { + try + { + return (T)InternalServices[typeof(T)]; + } + catch (KeyNotFoundException) + { + throw new ApplicationException("The requested service is not registered"); + } + } + + } +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta new file mode 100644 index 0000000..b557637 --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b894f2f07e31bcd49ac3a73d7507c2aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs index 89f8a1e..589d457 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs @@ -1,21 +1,35 @@ using Microsoft.Identity.Client; using System.Collections.Generic; +using System.Linq; using UnityEngine; public class StartupScript : MonoBehaviour { + public GameObject UnityWebBrowser; + // Use this for initialization void Start() { - var clientId = ""; + var clientId = "2437fe4e-b874-48ec-b3ee-e6658f6abdb9"; var scopes = new List() { "User.Read", }; var publicClientApplication = new PublicClientApplication(clientId); - var authenticationResult = publicClientApplication.AcquireTokenAsync(scopes).Result; + var user = publicClientApplication.Users.FirstOrDefault(); + + if (user == default(User)) + { + // No user in token cache + var authenticationResult = publicClientApplication.AcquireTokenAsync(scopes).Result; + } + else + { + // Call out to UI to get username and password + var authenticationResult = publicClientApplication.AcquireTokenSilentAsync(scopes, user).Result; + } } // Update is called once per frame diff --git a/Standalone-Samples/Unity-Identity/Unity-Identity.sln b/Standalone-Samples/Unity-Identity/Unity-Identity.sln new file mode 100644 index 0000000..9a707ad --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Unity-Identity.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity-Identity", "Assembly-CSharp.csproj", "{560AF659-E7F3-E280-76A2-B130C3C5C968}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {560AF659-E7F3-E280-76A2-B130C3C5C968}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {560AF659-E7F3-E280-76A2-B130C3C5C968}.Debug|Any CPU.Build.0 = Debug|Any CPU + {560AF659-E7F3-E280-76A2-B130C3C5C968}.Release|Any CPU.ActiveCfg = Release|Any CPU + {560AF659-E7F3-E280-76A2-B130C3C5C968}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From 8477a705850d91ba7ef04e8e8c8e52914b4e0ba6 Mon Sep 17 00:00:00 2001 From: Justin Wendlandt Date: Tue, 24 Jul 2018 12:53:26 -0700 Subject: [PATCH 3/5] Removing solution that's not needed anymore. --- .../Unity-Identity/TestingMsal.sln | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 Standalone-Samples/Unity-Identity/TestingMsal.sln diff --git a/Standalone-Samples/Unity-Identity/TestingMsal.sln b/Standalone-Samples/Unity-Identity/TestingMsal.sln deleted file mode 100644 index 859560f..0000000 --- a/Standalone-Samples/Unity-Identity/TestingMsal.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestingMsal", "Assembly-CSharp.csproj", "{0037223C-A948-414E-4BF6-F39E8B8A73BD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0037223C-A948-414E-4BF6-F39E8B8A73BD}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal From 36410964ce7a6026e8e06293840c7142ba81b7ad Mon Sep 17 00:00:00 2001 From: Justin Wendlandt Date: Tue, 24 Jul 2018 18:58:44 -0700 Subject: [PATCH 4/5] Got authentication working!!!!! --- .../Unity-Identity/Assembly-CSharp.csproj | 97 +-- .../Assets/Plugins/Newtonsoft.Json.dll | Bin 655872 -> 639488 bytes .../Assets/Scenes/SampleScene.unity | 5 +- .../AuthenticationResult.cs | 100 --- .../AuthenticationResult.cs.meta | 11 - .../ClientApplicationBase.cs | 251 ------ .../ClientApplicationBase.cs.meta | 11 - .../Microsoft.Identity.Client/Features.meta | 8 - .../Features/ConfidentialClient.meta | 8 - .../ClientAssertionCertificate.cs | 85 -- .../ConfidentialClient/ClientCredential.cs | 69 -- .../ClientCredential.cs.meta | 11 - .../ConfidentialClientApplication.cs | 246 ------ .../ConfidentialClientApplication.cs.meta | 11 - .../IConfidentialClientApplication.cs | 118 --- .../IConfidentialClientApplication.cs.meta | 11 - .../ConfidentialClient/JsonWebToken.cs | 225 ------ .../ConfidentialClient/JsonWebToken.cs.meta | 11 - .../Features/EventSource.meta | 8 - .../Features/EventSource/MsalEventSource.cs | 59 -- .../EventSource/MsalEventSource.cs.meta | 11 - .../Features/EventSource/PlatformLogger.cs | 67 -- .../EventSource/PlatformLogger.cs.meta | 11 - .../Features/PublicClient.meta | 8 - .../PublicClient/PublicClientApplication.cs | 47 -- .../PublicClientApplication.cs.meta | 11 - .../Features/TokenCache.meta | 8 - .../Features/TokenCache/TokenCacheAccessor.cs | 115 --- .../TokenCache/TokenCacheAccessor.cs.meta | 11 - .../TokenCache/TokenCacheExtensions.cs | 125 --- .../TokenCache/TokenCacheExtensions.cs.meta | 11 - .../IClientApplicationBase.cs | 115 --- .../IClientApplicationBase.cs.meta | 11 - .../IPublicClientApplication.cs | 240 ------ .../IPublicClientApplication.cs.meta | 11 - .../Microsoft.Identity.Client/IUser.cs | 57 -- .../Microsoft.Identity.Client/IUser.cs.meta | 11 - .../Microsoft.Identity.Client/Internal.meta | 8 - .../Internal/AuthorizationResult.cs | 124 --- .../Internal/AuthorizationResult.cs.meta | 11 - .../Internal/Base64UrlHelpers.cs | 108 --- .../Internal/Base64UrlHelpers.cs.meta | 11 - .../Internal/Cache.meta | 8 - .../Internal/Cache/AccessTokenCacheItem.cs | 140 ---- .../Cache/AccessTokenCacheItem.cs.meta | 11 - .../Internal/Cache/AccessTokenCacheKey.cs | 88 -- .../Cache/AccessTokenCacheKey.cs.meta | 11 - .../Internal/Cache/BaseTokenCacheItem.cs | 72 -- .../Internal/Cache/BaseTokenCacheItem.cs.meta | 11 - .../Internal/Cache/ITokenCacheAccessor.cs | 54 -- .../Cache/ITokenCacheAccessor.cs.meta | 11 - .../Internal/Cache/RefreshTokenCacheItem.cs | 95 --- .../Cache/RefreshTokenCacheItem.cs.meta | 11 - .../Internal/Cache/RefreshTokenCacheKey.cs | 57 -- .../Cache/RefreshTokenCacheKey.cs.meta | 11 - .../Internal/Cache/TokenCacheKeyBase.cs | 51 -- .../Internal/Cache/TokenCacheKeyBase.cs.meta | 11 - .../Internal/ClientInfo.cs | 86 -- .../Internal/ClientInfo.cs.meta | 11 - .../Internal/Constants.cs | 202 ----- .../Internal/Constants.cs.meta | 11 - .../Internal/Extensions.cs | 73 -- .../Internal/Extensions.cs.meta | 11 - .../Internal/Http.meta | 8 - .../Internal/Http/HttpClientFactory.cs | 76 -- .../Internal/Http/HttpClientFactory.cs.meta | 11 - .../Http/HttpMessageHandlerFactory.cs | 55 -- .../Http/HttpMessageHandlerFactory.cs.meta | 11 - .../Internal/Http/HttpRequest.cs | 180 ----- .../Internal/Http/HttpRequest.cs.meta | 11 - .../Internal/Http/HttpResponse.cs | 43 - .../Internal/Http/HttpResponse.cs.meta | 11 - .../Internal/ILogger.cs | 44 - .../Internal/ILogger.cs.meta | 11 - .../Internal/IdToken.cs | 112 --- .../Internal/IdToken.cs.meta | 11 - .../Internal/Instance.meta | 8 - .../Internal/Instance/AadAuthority.cs | 114 --- .../Internal/Instance/AadAuthority.cs.meta | 11 - .../Internal/Instance/AdfsAuthority.cs | 162 ---- .../Internal/Instance/AdfsAuthority.cs.meta | 11 - .../Instance/AdfsWebFingerResponse.cs | 61 -- .../Instance/AdfsWebFingerResponse.cs.meta | 11 - .../Internal/Instance/Authority.cs | 259 ------ .../Internal/Instance/Authority.cs.meta | 11 - .../Internal/Instance/B2CAuthority.cs | 63 -- .../Internal/Instance/B2CAuthority.cs.meta | 11 - .../Internal/Instance/DrsMetadataResponse.cs | 53 -- .../Instance/DrsMetadataResponse.cs.meta | 11 - .../Instance/InstanceDiscoveryResponse.cs | 39 - .../InstanceDiscoveryResponse.cs.meta | 11 - .../Instance/TenantDiscoveryResponse.cs | 52 -- .../Instance/TenantDiscoveryResponse.cs.meta | 11 - .../Internal/Interfaces.meta | 8 - .../Internal/Interfaces/IWebUI.cs | 41 - .../Internal/Interfaces/IWebUI.cs.meta | 11 - .../Internal/Interfaces/IWebUIFactory.cs | 34 - .../Internal/Interfaces/IWebUIFactory.cs.meta | 11 - .../Internal/JsonHelper.cs | 73 -- .../Internal/JsonHelper.cs.meta | 11 - .../Internal/MsalError.cs | 86 -- .../Internal/MsalError.cs.meta | 11 - .../Internal/MsalHelpers.cs | 378 --------- .../Internal/MsalHelpers.cs.meta | 11 - .../Internal/MsalIdHelper.cs | 125 --- .../Internal/MsalIdHelper.cs.meta | 11 - .../Internal/OAuth2.meta | 8 - .../Internal/OAuth2/OAuth2Client.cs | 198 ----- .../Internal/OAuth2/OAuth2Client.cs.meta | 11 - .../Internal/OAuth2/OAuth2ResponseBase.cs | 59 -- .../OAuth2/OAuth2ResponseBase.cs.meta | 11 - .../Internal/OAuth2/OAuthConstants.cs | 114 --- .../Internal/OAuth2/OAuthConstants.cs.meta | 11 - .../Internal/OAuth2/TokenResponse.cs | 74 -- .../Internal/OAuth2/TokenResponse.cs.meta | 11 - .../Internal/PlatformInformationBase.cs | 83 -- .../Internal/PlatformInformationBase.cs.meta | 11 - .../Internal/PlatformPlugin.cs | 98 --- .../Internal/PlatformPlugin.cs.meta | 11 - .../Internal/RequestContext.cs | 46 -- .../Internal/RequestContext.cs.meta | 11 - .../Internal/Requests.meta | 8 - .../AuthenticationRequestParameters.cs | 165 ---- .../AuthenticationRequestParameters.cs.meta | 11 - .../Requests/AuthorizationCodeRequest.cs | 61 -- .../Requests/AuthorizationCodeRequest.cs.meta | 11 - .../Requests/ClientCredentialRequest.cs | 72 -- .../Requests/ClientCredentialRequest.cs.meta | 11 - .../Internal/Requests/InteractiveRequest.cs | 274 ------- .../Requests/InteractiveRequest.cs.meta | 11 - .../Internal/Requests/OnBehalfOfRequest.cs | 77 -- .../Requests/OnBehalfOfRequest.cs.meta | 11 - .../Internal/Requests/RequestBase.cs | 315 -------- .../Internal/Requests/RequestBase.cs.meta | 11 - .../Internal/Requests/SilentRequest.cs | 108 --- .../Internal/Requests/SilentRequest.cs.meta | 11 - .../Internal/Telemetry.meta | 8 - .../Internal/Telemetry/ApiEvent.cs | 173 ---- .../Internal/Telemetry/ApiEvent.cs.meta | 11 - .../Internal/Telemetry/CacheEvent.cs | 67 -- .../Internal/Telemetry/CacheEvent.cs.meta | 11 - .../Internal/Telemetry/DefaultEvent.cs | 45 -- .../Internal/Telemetry/DefaultEvent.cs.meta | 11 - .../Internal/Telemetry/Event.cs | 90 --- .../Internal/Telemetry/Event.cs.meta | 11 - .../Internal/Telemetry/HttpEvent.cs | 93 --- .../Internal/Telemetry/HttpEvent.cs.meta | 11 - .../Telemetry/TelemetryTokenCacheAccessor.cs | 92 --- .../TelemetryTokenCacheAccessor.cs.meta | 11 - .../Internal/Telemetry/UiEvent.cs | 45 -- .../Internal/Telemetry/UiEvent.cs.meta | 11 - .../Microsoft.Identity.Client/Logger.cs | 267 ------- .../Microsoft.Identity.Client/Logger.cs.meta | 11 - .../MsalClientException.cs | 151 ---- .../MsalClientException.cs.meta | 11 - .../MsalException.cs | 117 --- .../MsalException.cs.meta | 11 - .../MsalServiceException.cs | 178 ----- .../MsalServiceException.cs.meta | 11 - .../MsalUiRequiredException.cs | 97 --- .../MsalUiRequiredException.cs.meta | 11 - .../Microsoft.Identity.Client/Platforms.meta | 8 - .../Platforms/Unity.meta | 8 - .../Platforms/Unity/CryptographyHelper.cs | 72 -- .../Unity/CryptographyHelper.cs.meta | 11 - .../Platforms/Unity/PlatformInformation.cs | 66 -- .../Unity/PlatformInformation.cs.meta | 11 - .../Platforms/Unity/UnityWebUI.cs | 20 - .../Platforms/Unity/UnityWebUI.cs.meta | 11 - .../Platforms/Unity/WebUIFactory.cs | 43 - .../Platforms/Unity/WebUIFactory.cs.meta | 11 - .../Microsoft.Identity.Client/Properties.meta | 8 - .../Properties/InternalsVisibleTo.cs | 14 - .../Properties/InternalsVisibleTo.cs.meta | 11 - .../Microsoft.Identity.Client.rd.xml | 33 - .../Microsoft.Identity.Client.rd.xml.meta | 7 - .../PublicClientApplication.cs | 380 --------- .../PublicClientApplication.cs.meta | 11 - .../Microsoft.Identity.Client/Resources.meta | 8 - .../Resources/AboutResources.txt | 50 -- .../Resources/AboutResources.txt.meta | 7 - .../Resources/Values.meta | 8 - .../Resources/Values/Strings.xml | 5 - .../Resources/Values/Strings.xml.meta | 7 - .../Resources/layout.meta | 8 - .../layout/WebAuthenticationBroker.axml | 12 - .../layout/WebAuthenticationBroker.axml.meta | 7 - .../Microsoft.Identity.Client/Telemetry.cs | 209 ----- .../Telemetry.cs.meta | 11 - .../Microsoft.Identity.Client/TokenCache.cs | 752 ------------------ .../TokenCache.cs.meta | 11 - .../TokenCacheNotificationArgs.cs | 50 -- .../TokenCacheNotificationArgs.cs.meta | 11 - .../Microsoft.Identity.Client/UIBehavior.cs | 111 --- .../UIBehavior.cs.meta | 11 - .../Microsoft.Identity.Client/UIParent.cs | 88 -- .../UIParent.cs.meta | 11 - .../Scripts/Microsoft.Identity.Client/User.cs | 79 -- .../Microsoft.Identity.Client/User.cs.meta | 11 - .../UserAssertion.cs | 84 -- .../UserAssertion.cs.meta | 11 - ...osoft.Identity.Client.meta => Models.meta} | 2 +- .../Assets/Scripts/Models/IdentityResult.cs | 17 + .../IdentityResult.cs.meta} | 2 +- .../Assets/Scripts/ServiceLocator.cs | 28 - .../Assets/Scripts/ServiceLocator.cs.meta | 11 - .../Assets/Scripts/StartupScript.cs | 83 +- 207 files changed, 91 insertions(+), 11615 deletions(-) delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/AuthenticationResult.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/AuthenticationResult.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta rename Standalone-Samples/Unity-Identity/Assets/Scripts/{Microsoft.Identity.Client.meta => Models.meta} (77%) create mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs rename Standalone-Samples/Unity-Identity/Assets/Scripts/{Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta => Models/IdentityResult.cs.meta} (83%) delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs delete mode 100644 Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta diff --git a/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj index c7b9e5c..5d2b6a4 100644 --- a/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj +++ b/Standalone-Samples/Unity-Identity/Assembly-CSharp.csproj @@ -60,97 +60,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll @@ -358,6 +269,9 @@ C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll + + C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll @@ -367,9 +281,6 @@ C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll - - C:/Source/GitHub/mixedreality-azure-samples/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll - C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/ref/2.0.0/netstandard.dll diff --git a/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll b/Standalone-Samples/Unity-Identity/Assets/Plugins/Newtonsoft.Json.dll index 63b1a9965e2aaacbfb65d68a4cff7e9554c9163b..d6e3d9d3d0c13daa1f68e25e244bd427012dfb02 100644 GIT binary patch literal 639488 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

U8>tT zg5YffPORJ73;GCu?bE$ay3OYVRNk$JQ!ah#M5y5QI60*}PjS0gY0(t`x8-=;R;t0= zwidnj<2I{lc@L{lQtaA!f7qaI%2D&Sbid|iGI2JqF%Ly(=* z*|Pb{f+$X9fJaVW7ZQYQZI6S#?w60ak3pZy+W`PKa`TKf8jdIGLLrN-+Cpw;N#wMO1ttDA1{)QsZSdg z6#y&cc&t>aL9Fb)*(lqSkWLl{Q<7))TueYrl@%fm6!|fgJ;PC{Zfk8Sr;LrtuqfuX zU}lX#7EGWar8OGIeS4jmW&Vcd?hT`Wg$;ahe*^Ez6hDZ0!=02c^8OxV3KPdq{hO4@P>a&<~y>r6G)_QlJ2Vb|nmvcJGec|8v z(kbF;U%52IR#R19xvYR=@vNFl(l|zUBYE=}s%uYHGr=Kn@^dDuA0!A_-4};%5&TZ| zO8tG9S0|tQ;dAd!DCf7wZ$nDtdP&;PQp@eL;SHFn-jcspAEKwKKK7%&IK+-F9Y_%M zaVSn~J3dIAY)JZ_@#lJ10=Vp&r^f`9T|5|cMZa*N?@Q&B4&o_&r%7+`|GnW-0QxS+ zV}nwm@5YAsihj_wXUxc&7L!Si4bf@y;a1b)T9mZbwXz%jB@T^I80@B zb-^7Bbl%$s4hxHd>H-G2p5?WgsJ`(Y%V3wp8$QERbxC{$>?F}2lTJg%)aUc$P%;tA zVOL+jy6hhTl6Kj1bmU(}tXBPvM+%)XmzqT;7b35dgSFG>E6&W>dBA$Xf-jgH9|

o9Kr2DnmBu|)hMi`* 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

?S$yLDvY17zOjv;|HiUE{F2r;bb2hI<)huN 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%0Dbg5!2QR`o;}gt$aLLuLB1)j8ST|$xfR8C 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�i_mg!O&`#pZoQFdcdw$4F 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 - /// Contains the results of one token acquisition operation. - /// - public class AuthenticationResult - { - private const string Oauth2AuthorizationHeader = "Bearer "; - private readonly AccessTokenCacheItem _accessTokenCacheItem; - - internal AuthenticationResult() - { - } - - internal AuthenticationResult(AccessTokenCacheItem accessTokenCacheItem) - { - _accessTokenCacheItem = accessTokenCacheItem; - } - - ///

- /// Gets the Access Token requested. - /// - public virtual string AccessToken => _accessTokenCacheItem.AccessToken; - - /// - /// Gets the Unique Id of the user. - /// - public virtual string UniqueId => _accessTokenCacheItem.IdToken?.GetUniqueId(); - - /// - /// Gets the point in time in which the Access Token returned in the Token property ceases to be valid. - /// This value is calculated based on current UTC time measured locally and the value expiresIn received from the - /// service. - /// - public virtual DateTimeOffset ExpiresOn => _accessTokenCacheItem.ExpiresOn; - - /// - /// Gets an identifier for the tenant the token was acquired from. This property will be null if tenant information is - /// not returned by the service. - /// - public virtual string TenantId => _accessTokenCacheItem.IdToken?.TenantId; - - /// - /// Gets the user object. Some elements in User might be null if not returned by the - /// service. It can be passed back in some API overloads to identify which user should be used. - /// - public virtual IUser User => _accessTokenCacheItem.User; - - /// - /// Gets the entire Id Token if returned by the service or null if no Id Token is returned. - /// - public virtual string IdToken => _accessTokenCacheItem.RawIdToken; - - /// - /// Gets the scope values returned from the service. - /// - public virtual IEnumerable Scopes => _accessTokenCacheItem.ScopeSet.AsArray(); - - /// - /// Creates authorization header from authentication result. - /// - /// Created authorization header - public virtual string CreateAuthorizationHeader() - { - return Oauth2AuthorizationHeader + AccessToken; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/AuthenticationResult.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/AuthenticationResult.cs.meta deleted file mode 100644 index bc8395a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/AuthenticationResult.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b8cfc31bfc28cbb4fbbd884c138a15a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs deleted file mode 100644 index 1776f9e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs +++ /dev/null @@ -1,251 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.Requests; -using System.Linq; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client -{ - /// - /// Abstract class containing common API methods and properties. Both PublicClientApplication and ConfidentialClientApplication extend this class. - /// - public abstract class ClientApplicationBase - { - private TokenCache _userTokenCache; - - /// - /// Default Authority used for interactive calls. - /// - protected const string DefaultAuthority = "https://login.microsoftonline.com/common/"; - - /// - /// - /// - /// - /// - /// - /// - protected ClientApplicationBase(string clientId, string authority, string redirectUri, - bool validateAuthority) - { - ClientId = clientId; - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, validateAuthority); - Authority = authorityInstance.CanonicalAuthority; - RedirectUri = redirectUri; - ValidateAuthority = validateAuthority; - if (UserTokenCache != null) - { - UserTokenCache.ClientId = clientId; - } - - RequestContext requestContext = new RequestContext(Guid.Empty, null); - - var msg = string.Format(CultureInfo.InvariantCulture, - "MSAL {0} with assembly version '{1}', file version '{2}' and informational version '{3}' is running...", - PlatformPlugin.PlatformInformation.GetProductName(), MsalIdHelper.GetMsalVersion(), - MsalIdHelper.GetAssemblyFileVersion(), MsalIdHelper.GetAssemblyInformationalVersion()); - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - } - - /// - /// Identifier of the component consuming MSAL and it is intended for libraries/SDKs that consume MSAL. This will allow for disambiguation between MSAL usage by the app vs MSAL usage by component libraries. - /// - public string Component { get; set; } - - /// - /// Authority provided by the developer or default authority used by the library. - /// - public string Authority { get; } - - /// - /// Will be a default value. Can be overridden by the developer. Once set, application will bind to the client Id. - /// - public string ClientId { get; } - - /// - /// Redirect Uri configured in the app registration portal. PublicClientApplication has a default value of - /// urn:ietf:wg:oauth:2.0:oob.This default does not apply to iOS and Android as the library needs to leverage - /// system webview for authentication. - /// - public string RedirectUri { get; set; } - - /// - /// Sets or Gets the custom query parameters that may be sent to the STS for dogfood testing. This parameter should not be set by the - /// developers as it may have adverse effect on the application. - /// - public string SliceParameters { get; set; } - - /// - /// Token Cache instance for storing User tokens. - /// - internal TokenCache UserTokenCache - { - get { return _userTokenCache; } - set - { - _userTokenCache = value; - if (_userTokenCache != null) - { - _userTokenCache.ClientId = ClientId; - } - } - } - - /// - /// Gets/sets a value indicating whether authority validation is ON or OFF. Value is true by default. - /// It should be set to false by the deveopers for B2C applications. - /// - public bool ValidateAuthority { get; set; } - - /// - /// Returns a User centric view over the cache that provides a list of all the available users in the cache for the application. - /// - public IEnumerable Users - { - get - { - RequestContext requestContext = new RequestContext(Guid.Empty, null); - if (UserTokenCache == null) - { - const string msg = "Token cache is null or empty. Returning empty list of users."; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - return Enumerable.Empty(); - } - - return UserTokenCache.GetUsers(new Uri(Authority).Host, requestContext); - } - } - - /// - /// Get user by identifier from users available in the cache. - /// - /// user identifier - public IUser GetUser(string identifier) - { - return Users.FirstOrDefault(user => user.Identifier.Equals(identifier)); - } - - /// - /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. - /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or - /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. - /// - /// Array of scopes requested for resource - /// User for which the token is requested. - /// - public async Task AcquireTokenSilentAsync(IEnumerable scopes, IUser user) - { - return - await - AcquireTokenSilentCommonAsync(null, scopes, user, false, ApiEvent.ApiIds.AcquireTokenSilentWithoutAuthority) - .ConfigureAwait(false); - } - - /// - /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. - /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or - /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. - /// - /// Array of scopes requested for resource - /// User for which the token is requested - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using the refresh token if available - /// - public async Task AcquireTokenSilentAsync(IEnumerable scopes, IUser user, - string authority, bool forceRefresh) - { - Authority authorityInstance = null; - if (!string.IsNullOrEmpty(authority)) - { - authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - } - - return - await - AcquireTokenSilentCommonAsync(authorityInstance, scopes, user, - forceRefresh, ApiEvent.ApiIds.AcquireTokenSilentWithAuthority).ConfigureAwait(false); - } - - /// - /// Removes all cached tokens for the specified user. - /// - /// instance of the user that needs to be removed - public void Remove(IUser user) - { - RequestContext requestContext = CreateRequestContext(Guid.Empty); - if (user == null || UserTokenCache == null) - { - return; - } - - UserTokenCache.Remove(user, requestContext); - } - - internal async Task AcquireTokenSilentCommonAsync(Authority authority, - IEnumerable scopes, IUser user, bool forceRefresh, ApiEvent.ApiIds apiId) - { - var handler = new SilentRequest( - CreateRequestParameters(authority, scopes, user, UserTokenCache), - forceRefresh) - { ApiId = apiId }; - return await handler.RunAsync().ConfigureAwait(false); - } - - internal virtual AuthenticationRequestParameters CreateRequestParameters(Authority authority, - IEnumerable scopes, - IUser user, TokenCache cache) - { - return new AuthenticationRequestParameters - { - SliceParameters = SliceParameters, - Authority = authority, - ClientId = ClientId, - TokenCache = cache, - User = user, - Scope = scopes.CreateSetFromEnumerable(), - RedirectUri = new Uri(RedirectUri), - RequestContext = CreateRequestContext(Guid.Empty), - ValidateAuthority = ValidateAuthority - }; - } - - internal RequestContext CreateRequestContext(Guid correlationId) - { - correlationId = (correlationId != Guid.Empty) ? correlationId : Guid.NewGuid(); - return new RequestContext(correlationId, Component); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta deleted file mode 100644 index 20d7237..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/ClientApplicationBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6664b1207e06edf41ae7e1ffa63c334c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta deleted file mode 100644 index 4b62472..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7d7b1f184e5dfe843a93ee6e3d0ae427 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta deleted file mode 100644 index 68058ba..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 73c1eb1ad8f8d4f47bb5c0ce9d6394f8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs deleted file mode 100644 index 7f5ff10..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs +++ /dev/null @@ -1,85 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client.Internal; -using System; -using System.Security.Cryptography.X509Certificates; - -namespace Microsoft.Identity.Client -{ - /// - /// Containing certificate used to create client assertion. - /// - public sealed class ClientAssertionCertificate - { - /// - /// Constructor to create credential using certificate. - /// - /// The certificate used as credential. - public ClientAssertionCertificate(X509Certificate2 certificate) - { - if (certificate == null) throw new ArgumentNullException(nameof(certificate)); - - Certificate = certificate; - -#if DESKTOP - if (certificate.PublicKey. Key.KeySize < MinKeySizeInBits) - { - throw new ArgumentOutOfRangeException(nameof(certificate), - string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.CertificateKeySizeTooSmallTemplate, - MinKeySizeInBits)); - } -#endif - - } - - /// - /// Gets minimum X509 certificate key size in bits - /// - public static int MinKeySizeInBits - { - get { return 2048; } - } - - /// - /// Gets the certificate used as credential. - /// - public X509Certificate2 Certificate { get; } - - internal byte[] Sign(string message) - { - CryptographyHelper helper = new CryptographyHelper(); - return helper.SignWithCertificate(message, Certificate); - } - - internal string Thumbprint - { - // Thumbprint should be url encoded - get { return Base64UrlHelpers.Encode(Certificate.GetCertHash()); } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs deleted file mode 100644 index f8656e2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs +++ /dev/null @@ -1,69 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client -{ - /// - /// Meant to be used in confidential client applications. Allows developers to - /// pass either client secret or client assertion certificate of their application. - /// - public sealed class ClientCredential - { -#if !FACADE - /// - /// Constructor provide client assertion certificate - /// - /// certificate of the client requesting the token. - public ClientCredential(ClientAssertionCertificate certificate) - { - Certificate = certificate; - } - - internal ClientAssertionCertificate Certificate { get; private set; } - internal string Assertion { get; set; } - internal long ValidTo { get; set; } -#endif - - /// - /// Constructor to provide client secret - /// - /// Secret of the client requesting the token. - public ClientCredential(string secret) - { - if (string.IsNullOrWhiteSpace(secret)) - { - throw new ArgumentNullException(nameof(secret)); - } - - Secret = secret; - } - - internal string Secret { get; private set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta deleted file mode 100644 index 688b757..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientCredential.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 90934d28eaf1f5d49b852704f94a85a8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs deleted file mode 100644 index 0e94609..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs +++ /dev/null @@ -1,246 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.Requests; -using Microsoft.Identity.Client.Internal.Telemetry; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client -{ - /// - /// Class to be used for confidential client applications like Web Apps/API. - /// - public sealed class ConfidentialClientApplication : ClientApplicationBase, IConfidentialClientApplication - { - /// - /// Constructor to create instance of the class - /// - /// Client Id of the application. REQUIRED. - /// Redirect URI of the application. REQUIRED. - /// Client credential for the application. Could be a certificate or a secret. REQUIRED. - /// Token cache for saving user tokens. OPTIONAL. - /// Token cache for saving application/client tokens. OPTIONAL. - public ConfidentialClientApplication(string clientId, string redirectUri, - ClientCredential clientCredential, TokenCache userTokenCache, TokenCache appTokenCache) - : this(clientId, DefaultAuthority, redirectUri, clientCredential, userTokenCache, appTokenCache) - { - } - - /// - /// Constructor to create instance of the class - /// - /// Client Id of the application. REQUIRED. - /// Authority to be used for the client application. REQUIRED. - /// Redirect URI of the application. REQUIRED. - /// Client credential for the application. Could be a certificate or a secret. REQUIRED. - /// Token cache for saving user tokens. OPTIONAL. - /// Token cache for saving application/client tokens. OPTIONAL. - public ConfidentialClientApplication(string clientId, string authority, string redirectUri, - ClientCredential clientCredential, TokenCache userTokenCache, TokenCache appTokenCache) - : base(clientId, authority, redirectUri, true) - { - ClientCredential = clientCredential; - UserTokenCache = userTokenCache; - if (UserTokenCache != null) - { - UserTokenCache.ClientId = clientId; - } - - AppTokenCache = appTokenCache; - if (AppTokenCache != null) - { - AppTokenCache.ClientId = clientId; - } - } - - /// - /// Acquires token using On-Behalf-Of flow. - /// - /// Array of scopes requested for resource - /// Instance of UserAssertion containing user's token. - /// Authentication result containing token of the user for the requested scopes - public async Task AcquireTokenOnBehalfOfAsync(IEnumerable scopes, UserAssertion userAssertion) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenOnBehalfCommonAsync(authority, scopes, userAssertion, ApiEvent.ApiIds.AcquireTokenOnBehalfOfWithScopeUser) - .ConfigureAwait(false); - } - - /// - /// Acquires token using On-Behalf-Of flow. - /// - /// Array of scopes requested for resource - /// Instance of UserAssertion containing user's token. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user for the requested scopes - public async Task AcquireTokenOnBehalfOfAsync(IEnumerable scopes, UserAssertion userAssertion, - string authority) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - return - await - AcquireTokenOnBehalfCommonAsync(authorityInstance, scopes, userAssertion, ApiEvent.ApiIds.AcquireTokenOnBehalfOfWithScopeUserAuthority) - .ConfigureAwait(false); - } - - /// - /// Acquires security token from the authority using authorization code previously received. - /// This method does not lookup token cache, but stores the result in it, so it can be looked up using other methods such as . - /// - /// The authorization code received from service authorization endpoint. - /// Array of scopes requested for resource - /// Authentication result containing token of the user for the requested scopes - public async Task AcquireTokenByAuthorizationCodeAsync(string authorizationCode, IEnumerable scopes) - { - return - await - AcquireTokenByAuthorizationCodeCommonAsync( - authorizationCode, scopes, new Uri(RedirectUri), - ApiEvent.ApiIds.AcquireTokenByAuthorizationCodeWithCodeScope).ConfigureAwait(false); - } - - /// - /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. - /// - /// Array of scopes requested for resource - /// Authentication result containing application token for the requested scopes - public async Task AcquireTokenForClientAsync(IEnumerable scopes) - { - return - await - AcquireTokenForClientCommonAsync(scopes, false, ApiEvent.ApiIds.AcquireTokenForClientWithScope).ConfigureAwait(false); - } - - /// - /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. - /// - /// Array of scopes requested for resource - /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using client credentials - /// Authentication result containing application token for the requested scopes - public async Task AcquireTokenForClientAsync(IEnumerable scopes, bool forceRefresh) - { - return - await - AcquireTokenForClientCommonAsync(scopes, forceRefresh, ApiEvent.ApiIds.AcquireTokenForClientWithScopeRefresh).ConfigureAwait(false); - } - - /// - /// Gets URL of the authorize endpoint including the query parameters. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// URL of the authorize endpoint including the query parameters. - public async Task GetAuthorizationRequestUrlAsync(IEnumerable scopes, string loginHint, - string extraQueryParameters) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - var requestParameters = - CreateRequestParameters(authority, scopes, null, UserTokenCache); - requestParameters.ClientId = ClientId; - requestParameters.ExtraQueryParameters = extraQueryParameters; - - var handler = - new InteractiveRequest(requestParameters, null, loginHint, UIBehavior.SelectAccount, null); - return await handler.CreateAuthorizationUriAsync().ConfigureAwait(false); - } - - /// - /// Gets URL of the authorize endpoint including the query parameters. - /// - /// Array of scopes requested for resource - /// Address to return to upon receiving a response from the authority. - /// Identifier of the user. Generally a UPN. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// URL of the authorize endpoint including the query parameters. - public async Task GetAuthorizationRequestUrlAsync(IEnumerable scopes, string redirectUri, string loginHint, - string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - var requestParameters = CreateRequestParameters(authorityInstance, scopes, null, - UserTokenCache); - requestParameters.RedirectUri = new Uri(redirectUri); - requestParameters.ClientId = ClientId; - requestParameters.ExtraQueryParameters = extraQueryParameters; - - var handler = - new InteractiveRequest(requestParameters, extraScopesToConsent, loginHint, UIBehavior.SelectAccount, null); - return await handler.CreateAuthorizationUriAsync().ConfigureAwait(false); - } - - internal ClientCredential ClientCredential { get; } - - internal TokenCache AppTokenCache { get; } - - private async Task AcquireTokenForClientCommonAsync(IEnumerable scopes, bool forceRefresh, ApiEvent.ApiIds apiId) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - AuthenticationRequestParameters parameters = CreateRequestParameters(authority, scopes, null, - AppTokenCache); - parameters.IsClientCredentialRequest = true; - var handler = new ClientCredentialRequest(parameters, forceRefresh) { ApiId = apiId, IsConfidentialClient = true }; - return await handler.RunAsync().ConfigureAwait(false); - } - - private async Task AcquireTokenOnBehalfCommonAsync(Authority authority, - IEnumerable scopes, UserAssertion userAssertion, ApiEvent.ApiIds apiId) - { - var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); - requestParams.UserAssertion = userAssertion; - var handler = new OnBehalfOfRequest(requestParams) { ApiId = apiId, IsConfidentialClient = true }; - return await handler.RunAsync().ConfigureAwait(false); - } - - private async Task AcquireTokenByAuthorizationCodeCommonAsync(string authorizationCode, - IEnumerable scopes, Uri redirectUri, ApiEvent.ApiIds apiId) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); - requestParams.AuthorizationCode = authorizationCode; - requestParams.RedirectUri = redirectUri; - var handler = - new AuthorizationCodeRequest(requestParams) { ApiId = apiId, IsConfidentialClient = true }; - return await handler.RunAsync().ConfigureAwait(false); - } - - internal override AuthenticationRequestParameters CreateRequestParameters(Authority authority, IEnumerable scopes, IUser user, TokenCache cache) - { - AuthenticationRequestParameters parameters = base.CreateRequestParameters(authority, scopes, user, cache); - parameters.ClientId = ClientId; - //parameters.ClientCredential = ClientCredential; - - return parameters; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta deleted file mode 100644 index 60004a4..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ConfidentialClientApplication.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 105ce650a2c65814eb36c0fecb04f442 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs deleted file mode 100644 index 2416021..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs +++ /dev/null @@ -1,118 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client -{ - /// - /// Component to be used for confidential client applications like Web Apps/API. - /// - public interface IConfidentialClientApplication : IClientApplicationBase - { - /// - /// Acquires token using On-Behalf-Of flow. - /// - /// Array of scopes requested for resource - /// Instance of UserAssertion containing user's token. - /// Authentication result containing token of the user for the requested scopes - Task AcquireTokenOnBehalfOfAsync( - IEnumerable scopes, - UserAssertion userAssertion); - - /// - /// Acquires token using On-Behalf-Of flow. - /// - /// Array of scopes requested for resource - /// Instance of UserAssertion containing user's token. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user for the requested scopes - Task AcquireTokenOnBehalfOfAsync( - IEnumerable scopes, - UserAssertion userAssertion, - string authority); - - /// - /// Acquires security token from the authority using authorization code previously received. - /// This method does not lookup token cache, but stores the result in it, so it can be looked up using other methods such as . - /// - /// The authorization code received from service authorization endpoint. - /// Array of scopes requested for resource - /// Authentication result containing token of the user for the requested scopes - Task AcquireTokenByAuthorizationCodeAsync( - string authorizationCode, - IEnumerable scopes); - - /// - /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. - /// - /// Array of scopes requested for resource - /// Authentication result containing application token for the requested scopes - Task AcquireTokenForClientAsync( - IEnumerable scopes); - - /// - /// Acquires token from the service for the confidential client. This method attempts to look up valid access token in the cache. - /// - /// Array of scopes requested for resource - /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using client credentials - /// Authentication result containing application token for the requested scopes - Task AcquireTokenForClientAsync( - IEnumerable scopes, - bool forceRefresh); - - /// - /// Gets URL of the authorize endpoint including the query parameters. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// URL of the authorize endpoint including the query parameters. - Task GetAuthorizationRequestUrlAsync( - IEnumerable scopes, - string loginHint, - string extraQueryParameters); - - /// - /// Gets URL of the authorize endpoint including the query parameters. - /// - /// Array of scopes requested for resource - /// Address to return to upon receiving a response from the authority. - /// Identifier of the user. Generally a UPN. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// URL of the authorize endpoint including the query parameters. - Task GetAuthorizationRequestUrlAsync( - IEnumerable scopes, - string redirectUri, - string loginHint, - string extraQueryParameters, IEnumerable extraScopesToConsent, string authority); - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta deleted file mode 100644 index b13f58d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/IConfidentialClientApplication.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 549c2f58fa622d24b95b97f8dd0eb416 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs deleted file mode 100644 index 4ce3edf..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs +++ /dev/null @@ -1,225 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client; -using System; -using System.Runtime.Serialization; -using System.Text; - -namespace Microsoft.Identity.Client.Internal.Jwt -{ - internal class JsonWebTokenConstants - { - public const uint JwtToAadLifetimeInSeconds = 60*10; // Ten minutes - public const string HeaderType = "JWT"; - - internal class Algorithms - { - public const string RsaSha256 = "RS256"; - public const string None = "none"; - } - - internal class ReservedClaims - { - public const string Audience = "aud"; - public const string Issuer = "iss"; - public const string Subject = "sub"; - public const string NotBefore = "nbf"; - public const string ExpiresOn = "exp"; - public const string JwtIdentifier = "jti"; - } - - internal class ReservedHeaderParameters - { - public const string Algorithm = "alg"; - public const string Type = "typ"; - public const string X509CertificateThumbprint = "kid"; - } - } - - internal class JsonWebToken - { - // (64K) This is an arbitrary large value for the token length. We can adjust it as needed. - private const int MaxTokenLength = 65536; - public readonly JWTPayload Payload; - - public JsonWebToken(string clientId, string audience) - { - DateTime validFrom = DateTime.UtcNow; - - DateTime validTo = validFrom + TimeSpan.FromSeconds(JsonWebTokenConstants.JwtToAadLifetimeInSeconds); - - Payload = new JWTPayload - { - Audience = audience, - Issuer = clientId, - ValidFrom = ConvertToTimeT(validFrom), - ValidTo = ConvertToTimeT(validTo), - Subject = clientId, - JwtIdentifier = Guid.NewGuid().ToString() - }; - } - - public string Sign(ClientAssertionCertificate credential) - { - // Base64Url encoded header and claims - string token = Encode(credential); - - // Length check before sign - if (MaxTokenLength < token.Length) - { - throw new MsalException(MsalError.EncodedTokenTooLong); - } - - return string.Concat(token, ".", UrlEncodeSegment(credential.Sign(token))); - } - - private static string EncodeSegment(string segment) - { - return UrlEncodeSegment(Encoding.UTF8.GetBytes(segment)); - } - - private static string UrlEncodeSegment(byte[] segment) - { - return Base64UrlHelpers.Encode(segment); - } - - private static string EncodeHeaderToJson(ClientAssertionCertificate credential) - { - JWTHeaderWithCertificate header = new JWTHeaderWithCertificate(credential); - return JsonHelper.SerializeToJson(header); - } - - internal static long ConvertToTimeT(DateTime time) - { - var startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); - TimeSpan diff = time - startTime; - return (long) (diff.TotalSeconds); - } - - private string Encode(ClientAssertionCertificate credential) - { - // Header segment - string jsonHeader = EncodeHeaderToJson(credential); - - string encodedHeader = EncodeSegment(jsonHeader); - - // Payload segment - string jsonPayload = JsonHelper.SerializeToJson(Payload); - - string encodedPayload = EncodeSegment(jsonPayload); - - return string.Concat(encodedHeader, ".", encodedPayload); - } - - [DataContract] - internal class JWTHeader - { - public JWTHeader(ClientAssertionCertificate credential) - { - Credential = credential; - } - - protected ClientAssertionCertificate Credential { get; } - - [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.Type)] - public static string Type - { - get { return JsonWebTokenConstants.HeaderType; } - - set - { - // This setter is required by DataContractJsonSerializer - } - } - - [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.Algorithm)] - public string Algorithm - { - get - { - return Credential == null - ? JsonWebTokenConstants.Algorithms.None - : JsonWebTokenConstants.Algorithms.RsaSha256; - } - - set - { - // This setter is required by DataContractJsonSerializer - } - } - } - - [DataContract] - internal class JWTPayload - { - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Audience)] - public string Audience { get; set; } - - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Issuer)] - public string Issuer { get; set; } - - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.NotBefore)] - public long ValidFrom { get; set; } - - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.ExpiresOn)] - public long ValidTo { get; set; } - - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.Subject, IsRequired = false, - EmitDefaultValue = false)] - public string Subject { get; set; } - - [DataMember(Name = JsonWebTokenConstants.ReservedClaims.JwtIdentifier, IsRequired = false, - EmitDefaultValue = false)] - public string JwtIdentifier { get; set; } - } - - [DataContract] - internal sealed class JWTHeaderWithCertificate : JWTHeader - { - public JWTHeaderWithCertificate(ClientAssertionCertificate credential) - : base(credential) - { - } - - [DataMember(Name = JsonWebTokenConstants.ReservedHeaderParameters.X509CertificateThumbprint)] - public string X509CertificateThumbprint - { - get - { - // Thumbprint should be url encoded - return Credential.Thumbprint; - } - - set - { - // This setter is required by DataContractJsonSerializer - } - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta deleted file mode 100644 index f32b241..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/JsonWebToken.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c7e486512ab0902468a90c835c205dd5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta deleted file mode 100644 index b18da13..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 35efa734661209d488390191f4d33b2e -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs deleted file mode 100644 index 2b0f8c4..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs +++ /dev/null @@ -1,59 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Diagnostics.Tracing; - -namespace Microsoft.Identity.Client.Internal.EventsSource -{ - [EventSource(Name = "Microsoft.Identity.Client")] - internal class MsalEventSource : EventSource - { - [Event(1, Level = EventLevel.Verbose)] - internal void Verbose(string message) - { - WriteEvent(1, message); - } - - [Event(2, Level = EventLevel.Informational)] - internal void Information(string message) - { - WriteEvent(2, message); - } - - [Event(3, Level = EventLevel.Warning)] - internal void Warning(string message) - { - WriteEvent(3, message); - } - - [Event(4, Level = EventLevel.Error)] - internal void Error(string message) - { - WriteEvent(4, message); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta deleted file mode 100644 index e464d0a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/MsalEventSource.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cc069cabc75b0114c9db963e813bc218 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs deleted file mode 100644 index 9009c20..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs +++ /dev/null @@ -1,67 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client.Internal.EventsSource -{ - internal class PlatformLogger : ILogger - { - static PlatformLogger() - { - MsalEventSource = new MsalEventSource(); - } - - internal static MsalEventSource MsalEventSource { get; } - - public void Error(string message) - { - MsalEventSource.Error(message); - } - - public void Warning(string message) - { - MsalEventSource.Error(message); - } - - public void Verbose(string message) - { - MsalEventSource.Error(message); - } - - public void Information(string message) - { - MsalEventSource.Error(message); - } - - public void Error(Exception ex) - { - Error(ex.ToString()); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta deleted file mode 100644 index 3605d3e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/EventSource/PlatformLogger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7ffe51c4e4d020e4cb510d1f9a6e429d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta deleted file mode 100644 index b7a75b8..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6dbcbfaf6cbdd574f9e598977e97b118 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs deleted file mode 100644 index 123d411..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs +++ /dev/null @@ -1,47 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client -{ - public sealed partial class PublicClientApplication : ClientApplicationBase - { - - /// - /// Constructor to create application instance. This constructor is only available for Desktop and NetCore apps - /// - /// Client id of the application - /// Default authority to be used for the application - /// Instance of TokenCache. - public PublicClientApplication(string clientId, string authority, TokenCache userTokenCache) : base(clientId, - authority, PlatformPlugin.PlatformInformation.GetDefaultRedirectUri(clientId), true) - { - UserTokenCache = userTokenCache; - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta deleted file mode 100644 index 8ee834d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/PublicClient/PublicClientApplication.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38db533a629e2e7478019095597d6f9b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta deleted file mode 100644 index bdcf1f5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9b090cd9b2db50a47a7ae0dcde7e099a -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs deleted file mode 100644 index 3d40e78..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs +++ /dev/null @@ -1,115 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System.Collections.Generic; -using System.Linq; -using System.Collections.Concurrent; -using System.Collections.ObjectModel; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Cache; - -namespace Microsoft.Identity.Client -{ - internal class TokenCacheAccessor : ITokenCacheAccessor - { - internal readonly IDictionary AccessTokenCacheDictionary = - new ConcurrentDictionary(); - - internal readonly IDictionary RefreshTokenCacheDictionary = - new ConcurrentDictionary(); - - public void SaveAccessToken(string cacheKey, string item) - { - AccessTokenCacheDictionary[cacheKey] = item; - } - - public void SaveRefreshToken(string cacheKey, string item) - { - RefreshTokenCacheDictionary[cacheKey] = item; - } - - public string GetRefreshToken(string refreshTokenKey) - { - if (!RefreshTokenCacheDictionary.ContainsKey(refreshTokenKey)) - { - return null; - } - - return RefreshTokenCacheDictionary[refreshTokenKey]; - } - - public void DeleteAccessToken(string cacheKey) - { - AccessTokenCacheDictionary.Remove(cacheKey); - } - - public void DeleteRefreshToken(string cacheKey) - { - RefreshTokenCacheDictionary.Remove(cacheKey); - } - - public ICollection GetAllAccessTokensAsString() - { - return - new ReadOnlyCollection( - AccessTokenCacheDictionary.Values.ToList()); - } - - public ICollection GetAllRefreshTokensAsString() - { - return - new ReadOnlyCollection( - RefreshTokenCacheDictionary.Values.ToList()); - } - - public ICollection GetAllAccessTokenKeys() - { - return - new ReadOnlyCollection( - AccessTokenCacheDictionary.Keys.ToList()); - } - - public ICollection GetAllRefreshTokenKeys() - { - return - new ReadOnlyCollection( - RefreshTokenCacheDictionary.Keys.ToList()); - } - - public void Clear() - { - foreach (var key in GetAllAccessTokenKeys()) - { - DeleteAccessToken(key); - } - - foreach (var key in GetAllRefreshTokenKeys()) - { - DeleteRefreshToken(key); - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta deleted file mode 100644 index 8ea94ba..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheAccessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ecafd7540c09b864599d7868c2ee3e80 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs deleted file mode 100644 index eda9888..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs +++ /dev/null @@ -1,125 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Cache; - -namespace Microsoft.Identity.Client -{ - /// - /// - /// - public static class TokenCacheExtensions - { - /// - /// - /// - /// - /// - public static void SetBeforeAccess(this TokenCache tokencache, TokenCache.TokenCacheNotification beforeAccess) - { - tokencache.BeforeAccess = beforeAccess; - } - - /// - /// - /// - /// - /// - public static void SetAfterAccess(this TokenCache tokencache, TokenCache.TokenCacheNotification afterAccess) - { - tokencache.AfterAccess = afterAccess; - } - - /// - /// - /// - /// - /// - public static void SetBeforeWrite(this TokenCache tokencache, TokenCache.TokenCacheNotification beforeWrite) - { - tokencache.BeforeWrite = beforeWrite; - } - - /// - /// - /// - /// - /// - public static void Deserialize(this TokenCache tokenCache, byte[] state) - { - lock (tokenCache.LockObject) - { - RequestContext requestContext = new RequestContext(Guid.Empty, null); - Dictionary> cacheDict = JsonHelper - .DeserializeFromJson>>(state); - if (cacheDict == null || cacheDict.Count == 0) - { - //TODO log about empty cache - return; - } - - if (cacheDict.ContainsKey("access_tokens")) - { - foreach (var atItem in cacheDict["access_tokens"]) - { - tokenCache.AddAccessTokenCacheItem(JsonHelper.DeserializeFromJson(atItem)); - } - } - - if (cacheDict.ContainsKey("refresh_tokens")) - { - foreach (var rtItem in cacheDict["refresh_tokens"]) - { - tokenCache.AddRefreshTokenCacheItem(JsonHelper.DeserializeFromJson(rtItem)); - } - } - } - } - - /// - /// - /// - /// - /// - public static byte[] Serialize(this TokenCache tokenCache) - { - // reads the underlying in-memory dictionary and dumps out the content as a JSON - lock (tokenCache.LockObject) - { - RequestContext requestContext = new RequestContext(Guid.Empty, null); - Dictionary> cacheDict = new Dictionary>(); - cacheDict["access_tokens"] = tokenCache.GetAllAccessTokenCacheItems(requestContext); - cacheDict["refresh_tokens"] = tokenCache.GetAllRefreshTokenCacheItems(requestContext); - return JsonHelper.SerializeToJson(cacheDict).ToByteArray(); - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta deleted file mode 100644 index 960c3f5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/TokenCache/TokenCacheExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bdbdc632ab443be43973089b7fd094e4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs deleted file mode 100644 index ccd8e21..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs +++ /dev/null @@ -1,115 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client -{ - /// - /// Component containing common validation methods - /// - public interface IClientApplicationBase - { - /// - /// Identifier of the component consuming MSAL and it is intended for libraries/SDKs that consume MSAL. This will allow for - /// disambiguation between MSAL usage by the app vs MSAL usage by component libraries. - /// - string Component { get; set; } - - /// - /// Authority provided by the developer or default authority used by the library. - /// - string Authority { get; } - - /// - /// Will be a default value. Can be overridden by the developer. Once set, application will bind to the client Id. - /// - string ClientId { get; } - - /// - /// Redirect Uri configured in the portal. Will have a default value. Not required if the developer is using the - /// default client Id. - /// - string RedirectUri { get; set; } - - /// - /// Gets a value indicating whether address validation is ON or OFF. - /// - bool ValidateAuthority { get; } - - /// - /// Returns a user-centric view over the cache that provides a list of all the available users in the cache. - /// - IEnumerable Users { get; } - - /// - /// Sets or Gets the custom query parameters that may be sent to the STS for dogfood testing. This parameter should not be set by the - /// developers as it may have adverse effect on the application. - /// - string SliceParameters { get; set; } - - /// - /// Get user by identifier from users available in the cache. - /// - /// user identifier - IUser GetUser(string identifier); - - /// - /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. - /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or - /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. - /// - /// Array of scopes requested for resource - /// User for which the token is requested. - Task AcquireTokenSilentAsync( - IEnumerable scopes, - IUser user); - - /// - /// Attempts to acquire the access token from cache. Access token is considered a match if it AT LEAST contains all the requested scopes. - /// This means that an access token with more scopes than requested could be returned as well. If access token is expired or - /// close to expiration (within 5 minute window), then refresh token (if available) is used to acquire a new access token by making a network call. - /// - /// Array of scopes requested for resource - /// User for which the token is requested - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// If TRUE, API will ignore the access token in the cache and attempt to acquire new access token using the refresh token if available - Task AcquireTokenSilentAsync( - IEnumerable scopes, - IUser user, - string authority, - bool forceRefresh); - - /// - /// Removes all cached tokens for the specified user. - /// - /// instance of the user that needs to be removed - void Remove(IUser user); - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta deleted file mode 100644 index 8def2fd..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IClientApplicationBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1e860bfdc4d7950468f027061ec0ba01 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs deleted file mode 100644 index 5701233..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs +++ /dev/null @@ -1,240 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client -{ - /// - /// Component to be used for native applications (Desktop/UWP/iOS/Android). - /// - public interface IPublicClientApplication : IClientApplicationBase - { - -#if WINRT - /// - /// - /// - bool UseCorporateNetwork { get; set; } -#endif - - // expose the interactive API without UIParent only for platforms that - // do not need it to operate like desktop, UWP, iOS. -#if !ANDROID - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Authentication result containing token of the user - Task AcquireTokenAsync(IEnumerable scopes); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint, - UIBehavior behavior, - string extraQueryParameters); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, - UIBehavior behavior, - string extraQueryParameters); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint, - UIBehavior behavior, - string extraQueryParameters, - IEnumerable extraScopesToConsent, string authority); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, - UIBehavior behavior, - string extraQueryParameters, - IEnumerable extraScopesToConsent, - string authority); - -#endif - - // these API methods are exposed on other platforms. - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync(IEnumerable scopes, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint, - UIBehavior behavior, - string extraQueryParameters, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, - UIBehavior behavior, - string extraQueryParameters, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - string loginHint, - UIBehavior behavior, - string extraQueryParameters, - IEnumerable extraScopesToConsent, string authority, UIParent parent); - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, - UIBehavior behavior, - string extraQueryParameters, - IEnumerable extraScopesToConsent, - string authority, UIParent parent); - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta deleted file mode 100644 index 3a2cc50..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IPublicClientApplication.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fe598b4394878774fa9349ed3719a0bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs deleted file mode 100644 index 3b659e0..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs +++ /dev/null @@ -1,57 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client -{ - /// - /// Contains information of a single user. This information is used for token cache lookup and enforcing the user session on STS authorize endpont. - /// - public interface IUser - { - /// - /// Gets a displayable value in UserPrincipalName (UPN) format. The value can be null. - /// - string DisplayableId { get; } - - /// - /// Gets given name of the user if provided by the service. If not, the value is null. - /// - string Name { get; } - - /// - /// Gets identity provider if returned by the service. If not, the value is null. - /// - string IdentityProvider { get; } - - /// - /// Gets an identifier for the user that is used by the library and the service as a strong handle to user identity. Cannot be null. - /// - string Identifier { get; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta deleted file mode 100644 index b5b1d98..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/IUser.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 609e2142a21058f489c0f4847697b8c1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta deleted file mode 100644 index 3f6c6ea..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 590cf9813e95eb74f9aa09c2eb4e73ee -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs deleted file mode 100644 index 5e7fd00..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs +++ /dev/null @@ -1,124 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal -{ - internal enum AuthorizationStatus - { - Success, - ErrorHttp, - ProtocolError, - UserCancel, - UnknownError - } - - internal class AuthorizationResult - { - internal AuthorizationResult(AuthorizationStatus status, string returnedUriInput) : this(status) - { - if (Status == AuthorizationStatus.UserCancel) - { - Error = MsalClientException.AuthenticationCanceledError; - ErrorDescription = MsalErrorMessage.AuthenticationCanceled; - } - else if (Status == AuthorizationStatus.UnknownError) - { - Error = MsalException.UnknownError; - ErrorDescription = MsalErrorMessage.Unknown; - } - else - { - ParseAuthorizeResponse(returnedUriInput); - } - } - - internal AuthorizationResult(AuthorizationStatus status) - { - Status = status; - } - - public AuthorizationStatus Status { get; private set; } - - public string Code { get; private set; } - - public string Error { get; set; } - - public string ErrorDescription { get; set; } - - public string State { get; set; } - - public void ParseAuthorizeResponse(string webAuthenticationResult) - { - var resultUri = new Uri(webAuthenticationResult); - - // NOTE: The Fragment property actually contains the leading '#' character and that must be dropped - string resultData = resultUri.Query; - - if (!string.IsNullOrWhiteSpace(resultData)) - { - // Remove the leading '?' first - Dictionary response = MsalHelpers.ParseKeyValueList(resultData.Substring(1), '&', - true, null); - - if (response.ContainsKey(OAuth2Parameter.State)) - { - State = response[OAuth2Parameter.State]; - } - - if (response.ContainsKey(TokenResponseClaim.Code)) - { - Code = response[TokenResponseClaim.Code]; - } - else if (response.ContainsKey(TokenResponseClaim.Error)) - { - Error = response[TokenResponseClaim.Error]; - ErrorDescription = response.ContainsKey(TokenResponseClaim.ErrorDescription) - ? response[TokenResponseClaim.ErrorDescription] - : null; - Status = AuthorizationStatus.ProtocolError; - } - else - { - Error = MsalError.AuthenticationFailed; - ErrorDescription = MsalErrorMessage.AuthorizationServerInvalidResponse; - Status = AuthorizationStatus.UnknownError; - } - } - else - { - Error = MsalError.AuthenticationFailed; - ErrorDescription = MsalErrorMessage.AuthorizationServerInvalidResponse; - Status = AuthorizationStatus.UnknownError; - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta deleted file mode 100644 index d3bc826..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/AuthorizationResult.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5436665cad532a249bd4336071119969 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs deleted file mode 100644 index 0e1d3b3..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs +++ /dev/null @@ -1,108 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; -using System.Text; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class Base64UrlHelpers - { - private const char Base64PadCharacter = '='; - private const char Base64Character62 = '+'; - private const char Base64Character63 = '/'; - private const char Base64UrlCharacter62 = '-'; - private const char Base64UrlCharacter63 = '_'; - private static readonly Encoding TextEncoding = Encoding.UTF8; - - private static readonly string DoubleBase64PadCharacter = string.Format(CultureInfo.InvariantCulture, "{0}{0}", - Base64PadCharacter); - - // - // The following functions perform base64url encoding which differs from regular base64 encoding as follows - // * padding is skipped so the pad character '=' doesn't have to be percent encoded - // * the 62nd and 63rd regular base64 encoding characters ('+' and '/') are replace with ('-' and '_') - // The changes make the encoding alphabet file and URL safe - // See RFC4648, section 5 for more info - // - public static string Encode(string arg) - { - if (arg == null) - { - return null; - } - - return Encode(TextEncoding.GetBytes(arg)); - } - - public static string DecodeToString(string arg) - { - byte[] decoded = DecodeToBytes(arg); - return MsalHelpers.CreateString(decoded); - } - - public static byte[] DecodeToBytes(string arg) - { - string s = arg; - s = s.Replace(Base64UrlCharacter62, Base64Character62); // 62nd char of encoding - s = s.Replace(Base64UrlCharacter63, Base64Character63); // 63rd char of encoding - - switch (s.Length%4) - { - // Pad - case 0: - break; // No pad chars in this case - case 2: - s += DoubleBase64PadCharacter; - break; // Two pad chars - case 3: - s += Base64PadCharacter; - break; // One pad char - default: - throw new ArgumentException("Illegal base64url string!", nameof(arg)); - } - - return Convert.FromBase64String(s); // Standard base64 decoder - } - - internal static string Encode(byte[] arg) - { - if (arg == null) - { - return null; - } - - string s = Convert.ToBase64String(arg); - s = s.Split(Base64PadCharacter)[0]; // Remove any trailing padding - s = s.Replace(Base64Character62, Base64UrlCharacter62); // 62nd char of encoding - s = s.Replace(Base64Character63, Base64UrlCharacter63); // 63rd char of encoding - - return s; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta deleted file mode 100644 index b665f84..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Base64UrlHelpers.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 872b6724b79420c4b974b99e739913cd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta deleted file mode 100644 index ec41e29..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a20fd9b49a977a444aecc63a5bc521e6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs deleted file mode 100644 index 7b084e5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs +++ /dev/null @@ -1,140 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - [DataContract] - internal class AccessTokenCacheItem : BaseTokenCacheItem - { - public AccessTokenCacheItem() - { - } - - public AccessTokenCacheItem(string authority, string clientId, TokenResponse response) - : base(clientId) - { - - TokenType = response.TokenType; - Scope = response.Scope; - Authority = authority; - if (response.AccessToken != null) - { - AccessToken = response.AccessToken; - ExpiresOnUnixTimestamp = MsalHelpers.DateTimeToUnixTimestamp(response.AccessTokenExpiresOn); - } - - RawClientInfo = response.ClientInfo; - RawIdToken = response.IdToken; - CreateDerivedProperties(); - } - - /// - /// Gets the AccessToken Type. - /// - [DataMember(Name = "token_type")] - public string TokenType { get; set; } - - /// - /// Gets the Access Token requested. - /// - [DataMember(Name = "access_token")] - public string AccessToken { get; set; } - - [DataMember(Name = "id_token")] - public string RawIdToken { get; set; } - - [DataMember(Name = "expires_on")] - public long ExpiresOnUnixTimestamp { get; set; } - - /// - /// Gets the Authority. - /// - [DataMember(Name = "authority")] - public string Authority { get; set; } - - /// - /// Gets the ScopeSet. - /// - [DataMember(Name = "scope")] - public string Scope { get; set; } - - [DataMember(Name = "user_assertion_hash")] - public string UserAssertionHash { get; set; } - - public SortedSet ScopeSet { get; set; } - - public IdToken IdToken { get; set; } - - public DateTimeOffset ExpiresOn - { - get - { - DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - return dtDateTime.AddSeconds(ExpiresOnUnixTimestamp).ToUniversalTime(); - } - set - { - DateTimeOffset ignored = value; - } - } - - public AccessTokenCacheKey GetAccessTokenItemKey() - { - return new AccessTokenCacheKey(Authority, ScopeSet, ClientId, GetUserIdentifier()); - } - - private void CreateDerivedProperties() - { - ScopeSet = Scope.AsSet(); - IdToken = IdToken.Parse(RawIdToken); - if (!string.IsNullOrEmpty(RawClientInfo)) - { - // this should only happen for client credentials. - ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); - } - - if (IdToken != null) - { - User = new User(GetUserIdentifier(), IdToken.PreferredUsername, IdToken.Name, IdToken.Issuer); - } - } - - // This method is called after the object - // is completely deserialized. - [OnDeserialized] - void OnDeserialized(StreamingContext context) - { - CreateDerivedProperties(); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta deleted file mode 100644 index ddc91a5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 94aef809369c54f479cd3e2fb0808868 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs deleted file mode 100644 index 6a964eb..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs +++ /dev/null @@ -1,88 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - /// - /// - /// - internal class AccessTokenCacheKey : TokenCacheKeyBase - { - public AccessTokenCacheKey(string authority, SortedSet scopes, string clientId, string userIdentifier) : base(clientId, userIdentifier) - { - Authority = authority; - Scope = scopes ?? new SortedSet(); - } - - public string Authority { get; } - - public SortedSet Scope { get; } - - /// - /// - /// - public override string ToString() - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(Base64UrlHelpers.Encode(Authority)); - stringBuilder.Append(CacheKeyDelimiter); - stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); - stringBuilder.Append(CacheKeyDelimiter); - // scope is treeSet to guarantee the order of the scopes when converting to string. - stringBuilder.Append(Base64UrlHelpers.Encode(Scope.AsSingleString())); - stringBuilder.Append(CacheKeyDelimiter); - stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); - - return stringBuilder.ToString(); - } - - internal bool ScopeEquals(SortedSet otherScope) - { - if (Scope == null) - { - return otherScope == null; - } - - if (otherScope == null) - { - return Scope == null; - } - - if (Scope.Count == otherScope.Count) - { - return Scope.Intersect(otherScope, StringComparer.OrdinalIgnoreCase).Count() == Scope.Count; - } - - return false; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta deleted file mode 100644 index 6762d57..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/AccessTokenCacheKey.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6af361badd3c0504188c3f0802d5093e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs deleted file mode 100644 index b6a10af..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs +++ /dev/null @@ -1,72 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Globalization; -using System.Runtime.Serialization; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - /// - /// Token cache item - /// - [DataContract] - internal abstract class BaseTokenCacheItem - { - private const int CacheVersion = 1; - - /// - /// Default constructor. - /// - public BaseTokenCacheItem(string clientId) - { - ClientId = clientId; - } - - public BaseTokenCacheItem() - { - } - - [DataMember(Name = "ver", IsRequired = false)] - public int Version { get; set; } = CacheVersion; - - [DataMember(Name = "client_info")] - public string RawClientInfo { get; set; } - - [DataMember(Name = "client_id")] - public string ClientId { get; set; } - - public ClientInfo ClientInfo { get; set; } - - public User User { get; set; } - - internal string GetUserIdentifier() - { - return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", Base64UrlHelpers.Encode(ClientInfo?.UniqueIdentifier), - Base64UrlHelpers.Encode(ClientInfo?.UniqueTenantIdentifier)); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta deleted file mode 100644 index 4734a63..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/BaseTokenCacheItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 081099b0b48a9964dbb81f6d2d96fe3e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs deleted file mode 100644 index 0712e4c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs +++ /dev/null @@ -1,54 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Collections.Generic; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - internal interface ITokenCacheAccessor - { - void SaveAccessToken(string cacheKey, string item); - - void SaveRefreshToken(string cacheKey, string item); - - string GetRefreshToken(string refreshTokenKey); - - void DeleteAccessToken(string cacheKey); - - void DeleteRefreshToken(string cacheKey); - - ICollection GetAllAccessTokensAsString(); - - ICollection GetAllRefreshTokensAsString(); - - ICollection GetAllAccessTokenKeys(); - - ICollection GetAllRefreshTokenKeys(); - - void Clear(); - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta deleted file mode 100644 index 8760ca2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/ITokenCacheAccessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 159657aa35708494ebe728baacfa9ae2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs deleted file mode 100644 index 08e998d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs +++ /dev/null @@ -1,95 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Globalization; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - [DataContract] - internal class RefreshTokenCacheItem : BaseTokenCacheItem - { - - public RefreshTokenCacheItem() - { - } - - public RefreshTokenCacheItem(string environment, string clientId, TokenResponse response) : base(clientId) - { - RefreshToken = response.RefreshToken; - Environment = environment; - PopulateIdentifiers(response); - } - - [DataMember(Name = "environment")] - public string Environment { get; set; } - - [DataMember(Name = "displayable_id")] - public string DisplayableId { get; internal set; } - - [DataMember(Name = "name")] - public string Name { get; internal set; } - - [DataMember(Name = "identity_provider")] - public string IdentityProvider { get; internal set; } - - [DataMember (Name = "refresh_token")] - public string RefreshToken { get; set; } - - public RefreshTokenCacheKey GetRefreshTokenItemKey() - { - return new RefreshTokenCacheKey(Environment, ClientId, GetUserIdentifier()); - } - - public void PopulateIdentifiers(TokenResponse response) - { - IdToken idToken = IdToken.Parse(response.IdToken); - RawClientInfo = response.ClientInfo; - ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); - - DisplayableId = idToken.PreferredUsername; - Name = idToken.Name; - IdentityProvider = idToken.Issuer; - - User = new User(GetUserIdentifier(), DisplayableId, Name, IdentityProvider); - } - - // This method is called after the object - // is completely deserialized. - [OnDeserialized] - void OnDeserialized(StreamingContext context) - { - if (!string.IsNullOrEmpty(RawClientInfo)) - { - ClientInfo = ClientInfo.CreateFromJson(RawClientInfo); - } - - User = new User(GetUserIdentifier(), DisplayableId, Name, IdentityProvider); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta deleted file mode 100644 index 4d28e23..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 22d4899d37896e1438f3b05292c2cbb4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs deleted file mode 100644 index 565b6b0..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs +++ /dev/null @@ -1,57 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Text; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - class RefreshTokenCacheKey : TokenCacheKeyBase - { - - public RefreshTokenCacheKey(string environment, string clientId, string userIdentifier) : base(clientId, userIdentifier) - { - Environment = environment; - } - - public string Environment { get; } - - /// - /// - /// - public override string ToString() - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(Base64UrlHelpers.Encode(Environment)); - stringBuilder.Append(CacheKeyDelimiter); - stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); - stringBuilder.Append(CacheKeyDelimiter); - stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); - - return stringBuilder.ToString(); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta deleted file mode 100644 index 48d2c59..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/RefreshTokenCacheKey.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2960a823130dd441a912072a1209385 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs deleted file mode 100644 index ec069bf..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs +++ /dev/null @@ -1,51 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client.Internal.Cache -{ - internal abstract class TokenCacheKeyBase - { - public const string CacheKeyDelimiter = "$"; - - public TokenCacheKeyBase(string clientId, string userIdentifier) - { - ClientId = clientId; - UserIdentifier = userIdentifier; - } - - public string ClientId { get; set; } - - public string UserIdentifier { get; set; } - - protected bool Equals(string string1, string string2) - { - return (string.Compare(string2, string1, StringComparison.OrdinalIgnoreCase) == 0); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta deleted file mode 100644 index 2dc21df..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Cache/TokenCacheKeyBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e6955c3f33cdcdd49aa5d67d2d515930 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs deleted file mode 100644 index aa7a960..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs +++ /dev/null @@ -1,86 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Runtime.Serialization; - -namespace Microsoft.Identity.Client.Internal -{ - internal class ClientInfoClaim - { - public const string UniqueIdentifier = "uid"; - public const string UnqiueTenantIdentifier = "utid"; - } - - [DataContract] - internal class ClientInfo - { - [DataMember(Name = ClientInfoClaim.UniqueIdentifier, IsRequired = false)] - public string UniqueIdentifier { get; set; } - - [DataMember(Name = ClientInfoClaim.UnqiueTenantIdentifier, IsRequired = false)] - public string UniqueTenantIdentifier { get; set; } - - public static ClientInfo CreateFromJson(string clientInfo) - { - if (string.IsNullOrEmpty(clientInfo)) - { - throw new MsalClientException(MsalClientException.JsonParseError, "client info is null"); - } - - try - { - return JsonHelper.DeserializeFromJson(Base64UrlHelpers.DecodeToBytes(clientInfo)); - } - catch (Exception exc) - { - throw new MsalClientException(MsalClientException.JsonParseError, - "Failed to parse the returned client info.", exc); - } - } - public static ClientInfo CreateFromEncodedString(string encodedUserIdentiier) - { - if (string.IsNullOrEmpty(encodedUserIdentiier)) - { - return null; - } - - string[] artifacts = encodedUserIdentiier.Split('.'); - - if (artifacts.Length == 0) - { - return null; - } - - return new ClientInfo() - { - UniqueIdentifier = Base64UrlHelpers.DecodeToString(artifacts[0]), - UniqueTenantIdentifier = Base64UrlHelpers.DecodeToString(artifacts[1]), - }; - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta deleted file mode 100644 index 3a7a328..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ClientInfo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7e3ebe8a6ea08024fa51eec8d8eb7d95 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs deleted file mode 100644 index f64e876..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs +++ /dev/null @@ -1,202 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Xml.Linq; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class MsalErrorEx - { - public const string UnauthorizedUserInformationAccess = "unauthorized_user_information_access"; - public const string CannotAccessUserInformation = "user_information_access_failed"; - public const string NeedToSetCallbackUriAsLocalSetting = "need_to_set_callback_uri_as_local_setting"; - public const string DeviceCodeAuthorizationPendingError = "authorization_pending"; - } - - internal static class MsalErrorMessageEx - { - public const string CannotAccessUserInformation = - "Cannot access user information. Check machine's Privacy settings or initialize UserCredential with userId"; - - public const string UnauthorizedUserInformationAccess = - "Unauthorized accessing user information. Check application's 'Enterprise Authentication' capability"; - - public const string NeedToSetCallbackUriAsLocalSetting = - "You need to add the value of WebAuthenticationBroker.GetCurrentApplicationCallbackUri() to an application's local setting named CurrentApplicationCallbackUri."; - } - - internal static class Constants - { - public const string MsAppScheme = "ms-app"; - public static readonly Uri SsoPlaceHolderUri = new Uri("https://sso"); - public const int ExpirationMarginInMinutes = 5; - public const int CodeVerifierLength = 128; - public const int CodeVerifierByteSize = 32; - } - - - /// - /// The active directory authentication error message. - /// - internal static class MsalErrorMessage - { - public const string AccessingMetadataDocumentFailed = "Accessing WS metadata exchange failed"; - - public const string AssemblyNotFoundTemplate = - "Assembly required for the platform not found. Make sure assembly '{0}' exists"; - - public const string AssemblyLoadFailedTemplate = - "Loading an assembly required for the platform failed. Make sure assembly for the correct platform '{0}' exists"; - - public const string NonHttpsRedirectNotSupported = "Non-HTTPS url redirect is not supported in webview"; - public const string AuthenticationUiFailed = "The browser based authentication dialog failed to complete"; - public const string AuthorityInvalidUriFormat = "'authority' should be in Uri format"; - public const string AuthorityNotSupported = "'authority' is not supported"; - public const string DeprecatedAuthorityError = "login.windows.net has been deprecated. Use login.microsoftonline.com instead."; - public const string AuthorityValidationFailed = "Authority validation failed"; - public const string AuthorityUriInsecure = "'authority' should use the 'https' scheme"; - - public const string B2cAuthorityUriInvalidPath = - "B2C 'authority' Uri should have at least 3 segments in the path (i.e. https:///tfp///...)"; - public const string AuthorityUriInvalidPath = - "'authority' Uri should have at least one segment in the path (i.e. https:////...)"; - - public const string AuthorizationServerInvalidResponse = "The authorization server returned an invalid response"; - - public const string CertificateKeySizeTooSmallTemplate = - "The certificate used must have a key size of at least {0} bits"; - - public const string EmailAddressSuffixMismatch = - "No identity provider email address suffix matches the provided address"; - - public const string EncodedTokenTooLong = "Encoded token size is beyond the upper limit"; - public const string FailedToAcquireTokenSilently = "Failed to acquire token silently. Call method AcquireToken"; - public const string FailedToRefreshToken = "Failed to refresh token"; - public const string FederatedServiceReturnedErrorTemplate = "Federated service at {0} returned error: {1}"; - public const string IdentityProtocolLoginUrlNull = "The LoginUrl property in identityProvider cannot be null"; - public const string IdentityProtocolMismatch = "No identity provider matches the requested protocol"; - - public const string IdentityProviderRequestFailed = - "Token request to identity provider failed. Check InnerException for more details"; - - public const string InvalidArgumentLength = "Parameter has invalid length"; - public const string InvalidAuthenticateHeaderFormat = "Invalid authenticate header format"; - public const string InvalidAuthorityTypeTemplate = "This method overload is not supported by '{0}'"; - public const string InvalidCredentialType = "Invalid credential type"; - public const string InvalidFormatParameterTemplate = "Parameter '{0}' has invalid format"; - public const string InvalidTokenCacheKeyFormat = "Invalid token cache key format"; - public const string MissingAuthenticateHeader = "WWW-Authenticate header was expected in the response"; - - public const string MultipleTokensMatched = - "The cache contains multiple tokens satisfying the requirements. Call AcquireToken again providing more requirements like authority"; - - public const string NetworkNotAvailable = "The network is down so authentication cannot proceed"; - public const string NoDataFromSTS = "No data received from security token service"; - public const string NullParameterTemplate = "Parameter '{0}' cannot be null"; - public const string ParsingMetadataDocumentFailed = "Parsing WS metadata exchange failed"; - public const string ParsingWsTrustResponseFailed = "Parsing WS-Trust response failed"; - public const string PasswordRequiredForManagedUserError = "Password is required for managed user"; - public const string RedirectUriContainsFragment = "'redirectUri' must NOT include a fragment component"; - public const string LoginHintNullForUiOption = "Null login_hint is not allowed for UIBehavior.ActAsCurrentUser"; - public const string ServiceReturnedError = "Service returned error. Check InnerException for more details"; - - public const string BrokerReponseHashMismatch = - "Unencrypted broker response hash did not match the expected hash"; - - public const string StsMetadataRequestFailed = - "Metadata request to Access Control service failed. Check InnerException for more details"; - - public const string StsTokenRequestFailed = - "Token request to security token service failed. Check InnerException for more details"; - - public const string UnauthorizedHttpStatusCodeExpected = - "Unauthorized Http Status Code (401) was expected in the response"; - - public const string UnauthorizedResponseExpected = "Unauthorized http response (status code 401) was expected"; - public const string UnexpectedAuthorityValidList = "Unexpected list of valid addresses"; - public const string Unknown = "Unknown error"; - public const string UnknownUser = "Could not identify logged in user"; - public const string UnsupportedUserType = "Unsupported User Type"; - - public const string UnsupportedAuthorityValidation = - "Authority validation is not supported for this type of authority"; - - public const string UnsupportedMultiRefreshToken = - "This authority does not support refresh token for multiple resources. Pass null as a resource"; - - public const string AuthenticationCanceled = "User canceled authentication"; - public const string UserMismatch = "User '{0}' returned by service does not match user '{1}' in the request"; - public const string UserCredentialAssertionTypeEmpty = "credential.AssertionType cannot be empty"; - - public const string NoPromptFailedErrorMessage = - "One of two conditions was encountered: " - + - "1. The UiBehavior.Never flag was passed, but the constraint could not be honored, because user interaction was required. " - + - "2. An error occurred during a silent web authentication that prevented the http authentication flow from completing in a short enough time frame"; - - public const string UserRealmDiscoveryFailed = "User realm discovery failed"; - - public const string WsTrustEndpointNotFoundInMetadataDocument = - "WS-Trust endpoint not found in metadata document"; - - public const string GetUserNameFailed = "Failed to get user name"; - - public const string MissingFederationMetadataUrl = - "Federation Metadata Url is missing for federated user. This user type is unsupported."; - - public const string SpecifyAnyUser = - "If you do not need access token for any specific user, pass userId=UserIdentifier.AnyUser instead of userId=null."; - - public const string IntegratedAuthFailed = - "Integrated authentication failed. You may try an alternative authentication method"; - - public const string DuplicateQueryParameterTemplate = "Duplicate query parameter '{0}' in extraQueryParameters"; - public const string DeviceCertificateNotFoundTemplate = "Device Certificate was not found for {0}"; - } - - internal class XmlNamespace - { - public static readonly XNamespace Wsdl = "http://schemas.xmlsoap.org/wsdl/"; - public static readonly XNamespace Wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy"; - public static readonly XNamespace Http = "http://schemas.microsoft.com/ws/06/2004/policy/http"; - public static readonly XNamespace Sp = "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"; - public static readonly XNamespace Sp2005 = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"; - - public static readonly XNamespace Wsu = - "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; - - public static readonly XNamespace Soap12 = "http://schemas.xmlsoap.org/wsdl/soap12/"; - public static readonly XNamespace Wsa10 = "http://www.w3.org/2005/08/addressing"; - public static readonly XNamespace Trust = "http://docs.oasis-open.org/ws-sx/ws-trust/200512"; - public static readonly XNamespace Trust2005 = "http://schemas.xmlsoap.org/ws/2005/02/trust"; - public static readonly XNamespace Issue = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue"; - public static readonly XNamespace Issue2005 = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue"; - public static readonly XNamespace SoapEnvelope = "http://www.w3.org/2003/05/soap-envelope"; - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta deleted file mode 100644 index 762f085..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Constants.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3bd2e6e1ca085814daa6fd1dc5269a71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs deleted file mode 100644 index d493d05..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs +++ /dev/null @@ -1,73 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; -using System.Text; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class Extensions - { - internal static string GetPiiScrubbedDetails(this Exception ex) - { - string result = null; - if (ex != null) - { - var sb = new StringBuilder(); - - sb.Append(string.Format(CultureInfo.CurrentCulture, "Exception type: {0}", ex.GetType())); - - var msalException = ex as MsalException; - if (msalException != null) - { - sb.Append(string.Format(CultureInfo.CurrentCulture, ", ErrorCode: {0}", msalException.ErrorCode)); - } - - var msalServiceException = ex as MsalServiceException; - if (msalServiceException != null) - { - sb.Append(string.Format(CultureInfo.CurrentCulture, ", StatusCode: {0}", msalServiceException.StatusCode)); - } - - if (ex.InnerException != null) - { - sb.Append("---> " + GetPiiScrubbedDetails(ex.InnerException) + Environment.NewLine + "=== End of inner exception stack trace ==="); - } - - if (ex.StackTrace != null) - { - sb.Append(Environment.NewLine + ex.StackTrace); - } - - result = sb.ToString(); - } - - return result; - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta deleted file mode 100644 index d8eb1d7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Extensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: da4b5ea6f7e14c440be0cc0b12253ee7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta deleted file mode 100644 index 175294b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 86835f11e65c98a419f1ed93ac731350 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs deleted file mode 100644 index 3ded9b1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs +++ /dev/null @@ -1,76 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Net.Http; - -namespace Microsoft.Identity.Client.Internal.Http -{ - internal class HttpClientFactory - { - // as per guidelines HttpClient should be a singeton instance in an application. - private static HttpClient _client; - private static readonly object LockObj = new object(); - public static bool ReturnHttpClientForMocks { set; get; } - public const long MaxResponseContentBufferSizeInBytes = 1024*1024; - - private static HttpClient CreateHttpClient() - { - var httpClient = new HttpClient(HttpMessageHandlerFactory.GetMessageHandler(ReturnHttpClientForMocks)) - { - MaxResponseContentBufferSize = MaxResponseContentBufferSizeInBytes - }; - - return httpClient; - } - - public static HttpClient GetHttpClient() - { - // we return a new instanceof httpclient beacause there - // is no way to provide new http request message handler - // for each request made and it makes mocking of network calls - // impossible. So to circumvent, we simply return new instance for - // for mocking purposes. - if (ReturnHttpClientForMocks) - { - return CreateHttpClient(); - } - - if (_client == null) - { - lock (LockObj) - { - if (_client == null) - { - _client = CreateHttpClient(); - } - } - } - - return _client; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta deleted file mode 100644 index 35614f9..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpClientFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 05fc9d2ee1cb7744baee182518e704c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs deleted file mode 100644 index 7dfc8f3..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs +++ /dev/null @@ -1,55 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Collections.Generic; -using System.Net.Http; - -namespace Microsoft.Identity.Client.Internal.Http -{ - internal static class HttpMessageHandlerFactory - { - private static readonly Queue MockHttpMessageHandlerQueue = new Queue(); - - internal static HttpMessageHandler GetMessageHandler(bool forMock) - { - return forMock ? MockHttpMessageHandlerQueue.Dequeue() : new HttpClientHandler(); - } - - internal static void AddMockHandler(HttpMessageHandler mockHandler) - { - MockHttpMessageHandlerQueue.Enqueue(mockHandler); - } - - internal static void ClearMockHandlers() - { - MockHttpMessageHandlerQueue.Clear(); - } - - internal static bool IsMocksQueueEmpty => MockHttpMessageHandlerQueue.Count == 0; - internal static int MockCount => MockHttpMessageHandlerQueue.Count; - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta deleted file mode 100644 index d910f0a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpMessageHandlerFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 57cc1b234be08c847b8d2ae9f838df4c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs deleted file mode 100644 index 7a49ade..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs +++ /dev/null @@ -1,180 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client.Internal.Http -{ - internal class HttpRequest - { - private HttpRequest() - { - } - - public static async Task SendPostAsync(Uri endpoint, Dictionary headers, - Dictionary bodyParameters, RequestContext requestContext) - { - return - await - ExecuteWithRetryAsync(endpoint, headers, bodyParameters, HttpMethod.Post, requestContext) - .ConfigureAwait(false); - } - - public static async Task SendGetAsync(Uri endpoint, Dictionary headers, - RequestContext requestContext) - { - return await ExecuteWithRetryAsync(endpoint, headers, null, HttpMethod.Get, requestContext).ConfigureAwait(false); - } - - private static HttpRequestMessage CreateRequestMessage(Uri endpoint, Dictionary headers) - { - HttpRequestMessage requestMessage = new HttpRequestMessage { RequestUri = endpoint }; - requestMessage.Headers.Accept.Clear(); - if (headers != null) - { - foreach (KeyValuePair kvp in headers) - { - requestMessage.Headers.Add(kvp.Key, kvp.Value); - } - } - - return requestMessage; - } - - private static async Task ExecuteWithRetryAsync(Uri endpoint, Dictionary headers, - Dictionary bodyParameters, HttpMethod method, - RequestContext requestContext, bool retry = true) - { - Exception toThrow = null; - bool isRetryable = false; - HttpResponse response = null; - try - { - response = await ExecuteAsync(endpoint, headers, bodyParameters, method).ConfigureAwait(false); - - if (response.StatusCode == HttpStatusCode.OK) - { - return response; - } - - var msg = string.Format(CultureInfo.InvariantCulture, - "Response status code does not indicate success: {0} ({1}).", - (int) response.StatusCode, response.StatusCode); - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - - if ((int)response.StatusCode >= 500 && (int)response.StatusCode < 600) - { - isRetryable = true; - } - } - catch (TaskCanceledException exception) - { - requestContext.Logger.Error(exception); - requestContext.Logger.ErrorPii(exception); - isRetryable = true; - toThrow = exception; - } - - if (isRetryable) - { - if (retry) - { - const string msg = "Retrying one more time.."; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); - return await ExecuteWithRetryAsync(endpoint, headers, bodyParameters, method, requestContext, false).ConfigureAwait(false); - } - - const string message = "Request retry failed."; - requestContext.Logger.Info(message); - requestContext.Logger.InfoPii(message); - if (toThrow != null) - { - throw new MsalServiceException(MsalServiceException.RequestTimeout, "Request to the endpoint timed out.", toThrow); - } - - throw new MsalServiceException(MsalServiceException.ServiceNotAvailable, - "Service is unavailable to process the request", (int) response.StatusCode); - } - - return response; - } - - private static async Task ExecuteAsync(Uri endpoint, Dictionary headers, - Dictionary bodyParameters, HttpMethod method) - { - HttpClient client = HttpClientFactory.GetHttpClient(); - client.DefaultRequestHeaders.Accept.Clear(); - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - - using (HttpRequestMessage requestMessage = CreateRequestMessage(endpoint, headers)) - { - requestMessage.Method = method; - if (bodyParameters != null) - { - requestMessage.Content = new FormUrlEncodedContent(bodyParameters); - } - - using (HttpResponseMessage responseMessage = - await client.SendAsync(requestMessage).ConfigureAwait(false)) - { - HttpResponse returnValue = await CreateResponseAsync(responseMessage).ConfigureAwait(false); - returnValue.UserAgent = client.DefaultRequestHeaders.UserAgent.ToString(); - return returnValue; - } - } - } - - private static async Task CreateResponseAsync(HttpResponseMessage response) - { - var headers = new Dictionary(); - if (response.Headers != null) - { - foreach (var kvp in response.Headers) - { - headers[kvp.Key] = kvp.Value.First(); - } - } - - return new HttpResponse - { - Headers = headers, - Body = await response.Content.ReadAsStringAsync().ConfigureAwait(false), - StatusCode = response.StatusCode - }; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta deleted file mode 100644 index 6393132..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2325359f719b7fb45907a8d14b37b2db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs deleted file mode 100644 index 4e80e91..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs +++ /dev/null @@ -1,43 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Collections.Generic; -using System.Net; - -namespace Microsoft.Identity.Client.Internal.Http -{ - internal class HttpResponse - { - public Dictionary Headers { get; set; } - - public string Body { get; set; } - - public HttpStatusCode StatusCode { get; set; } - - public string UserAgent { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta deleted file mode 100644 index 6d5c581..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Http/HttpResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8e4a8a0f2b597a648bbd72155b94a0bf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs deleted file mode 100644 index 46217b9..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs +++ /dev/null @@ -1,44 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client.Internal -{ - internal interface ILogger - { - void Error(string message); - - void Warning(string message); - - void Information(string message); - - void Verbose(string message); - - void Error(Exception ex); - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta deleted file mode 100644 index 115ec67..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/ILogger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d4f2a2895d1eff14f931137a16391012 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs deleted file mode 100644 index 21da5d8..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs +++ /dev/null @@ -1,112 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; - -namespace Microsoft.Identity.Client.Internal -{ - internal class IdTokenClaim - { - public const string Issuer = "iss"; - public const string ObjectId = "oid"; - public const string Subject = "sub"; - public const string TenantId = "tid"; - public const string Version = "ver"; - public const string PreferredUsername = "preferred_username"; - public const string Name = "name"; - public const string HomeObjectId = "home_oid"; - } - - [DataContract] - internal class IdToken - { - [DataMember(Name = IdTokenClaim.Issuer, IsRequired = false)] - public string Issuer { get; set; } - - [DataMember(Name = IdTokenClaim.ObjectId, IsRequired = false)] - public string ObjectId { get; set; } - - [DataMember(Name = IdTokenClaim.Subject, IsRequired = false)] - public string Subject { get; set; } - - [DataMember(Name = IdTokenClaim.TenantId, IsRequired = false)] - public string TenantId { get; set; } - - [DataMember(Name = IdTokenClaim.Version, IsRequired = false)] - public string Version { get; set; } - - [DataMember(Name = IdTokenClaim.PreferredUsername, IsRequired = false)] - public string PreferredUsername { get; set; } - - [DataMember(Name = IdTokenClaim.Name, IsRequired = false)] - public string Name { get; set; } - - [DataMember(Name = IdTokenClaim.HomeObjectId, IsRequired = false)] - public string HomeObjectId { get; set; } - - public static IdToken Parse(string idToken) - { - if (string.IsNullOrEmpty(idToken)) - { - return null; - } - - IdToken idTokenBody = null; - string[] idTokenSegments = idToken.Split(new[] {'.'}); - - if (idTokenSegments.Length < 2) - { - throw new MsalClientException(MsalClientException.InvalidJwtError, "ID Token must contain at least 2 parts."); - } - - try - { - byte[] idTokenBytes = Base64UrlHelpers.DecodeToBytes(idTokenSegments[1]); - using (var stream = new MemoryStream(idTokenBytes)) - { - var serializer = new DataContractJsonSerializer(typeof(IdToken)); - idTokenBody = (IdToken) serializer.ReadObject(stream); - } - } - catch (Exception exc) - { - throw new MsalClientException(MsalClientException.JsonParseError, - "Failed to parse the returned id token.", exc); - } - - return idTokenBody; - } - - public string GetUniqueId() - { - return ObjectId ?? Subject; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta deleted file mode 100644 index b2fd8c7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/IdToken.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9468d6f6518f2e4e8e07ec09e60bf11 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta deleted file mode 100644 index 45d90f9..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 32847ba824167b1468e3c15cbb573fdc -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs deleted file mode 100644 index 4f7cdc2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs +++ /dev/null @@ -1,114 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class AadAuthority : Authority - { - private const string AadInstanceDiscoveryEndpoint = "https://login.microsoftonline.com/common/discovery/instance"; - private static readonly HashSet TrustedHostList = new HashSet() - { - "login.windows.net", // Microsoft Azure Worldwide - "login.chinacloudapi.cn", // Microsoft Azure China - "login.cloudgovapi.us", // Microsoft Azure US Government - "login.microsoftonline.us", // Microsoft Azure US Government - "login.microsoftonline.com", // Microsoft Azure Worldwide - "login.microsoftonline.de" // Microsoft Azure Blackforest - }; - - public AadAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) - { - AuthorityType = AuthorityType.Aad; - UpdateCanonicalAuthority(); - } - - protected void UpdateCanonicalAuthority() - { - UriBuilder uriBuilder = new UriBuilder(CanonicalAuthority); - if (uriBuilder.Host.Equals("login.windows.net", StringComparison.OrdinalIgnoreCase)) - { - uriBuilder.Host = "login.microsoftonline.com"; - } - - CanonicalAuthority = uriBuilder.Uri.AbsoluteUri; - } - - protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, - RequestContext requestContext) - { - - if (ValidateAuthority && !IsInTrustedHostList(new Uri(CanonicalAuthority).Host)) - { - OAuth2Client client = new OAuth2Client(); - client.AddQueryParameter("api-version", "1.0"); - client.AddQueryParameter("authorization_endpoint", CanonicalAuthority + "oauth2/v2.0/authorize"); - - InstanceDiscoveryResponse discoveryResponse = - await - client.DiscoverAadInstanceAsync(new Uri(AadInstanceDiscoveryEndpoint), requestContext) - .ConfigureAwait(false); - if (discoveryResponse.TenantDiscoveryEndpoint == null) - { - throw new MsalServiceException(discoveryResponse.Error, discoveryResponse.ErrorDescription); - } - - return discoveryResponse.TenantDiscoveryEndpoint; - } - - return GetDefaultOpenIdConfigurationEndpoint(); - } - - protected override bool ExistsInValidatedAuthorityCache(string userPrincipalName) - { - return ValidatedAuthorities.ContainsKey(CanonicalAuthority); - } - - protected override void AddToValidatedAuthorities(string userPrincipalName) - { - // add to the list of validated authorities so that we don't do openid configuration call - ValidatedAuthorities[CanonicalAuthority] = this; - } - - protected override string GetDefaultOpenIdConfigurationEndpoint() - { - return CanonicalAuthority + "v2.0/.well-known/openid-configuration"; - } - - internal static bool IsInTrustedHostList(string host) - { - return - !string.IsNullOrEmpty( - TrustedHostList.FirstOrDefault(a => string.Compare(host, a, StringComparison.OrdinalIgnoreCase) == 0)); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta deleted file mode 100644 index 28f7bfe..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AadAuthority.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 97fabd328f5fca042b9f9a4a63108a2a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs deleted file mode 100644 index a115cd2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs +++ /dev/null @@ -1,162 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted free of charge to any person obtaining a copy -// of this software and associated documentation files(the "Software") to deal -// in the Software without restriction including without limitation the rights -// to use copy modify merge publish distribute sublicense and / or sell -// copies of the Software and to permit persons to whom the Software is -// furnished to do so subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR -// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER -// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.Http; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class AdfsAuthority : Authority - { - private const string DefaultRealm = "http://schemas.microsoft.com/rel/trusted-realm"; - private readonly HashSet _validForDomainsList = new HashSet(); - public AdfsAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) - { - AuthorityType = AuthorityType.Adfs; - } - - protected override bool ExistsInValidatedAuthorityCache(string userPrincipalName) - { - if (string.IsNullOrEmpty(userPrincipalName)) - { - throw new MsalException("UPN is required for ADFS authority validation."); - } - - return ValidatedAuthorities.ContainsKey(CanonicalAuthority) && - ((AdfsAuthority) ValidatedAuthorities[CanonicalAuthority])._validForDomainsList.Contains( - GetDomainFromUpn(userPrincipalName)); - } - - protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext) - { - if (ValidateAuthority) - { - DrsMetadataResponse drsResponse = await GetMetadataFromEnrollmentServerAsync(userPrincipalName, requestContext).ConfigureAwait(false); - if (!string.IsNullOrEmpty(drsResponse.Error)) - { - throw new MsalServiceException(drsResponse.Error, drsResponse.ErrorDescription); - } - - if (drsResponse.IdentityProviderService?.PassiveAuthEndpoint == null) - { - throw new MsalServiceException("missing_passive_auth_endpoint", "missing_passive_auth_endpoint"); - } - - string resource = string.Format(CultureInfo.InvariantCulture, CanonicalAuthority); - string webfingerUrl = string.Format(CultureInfo.InvariantCulture, - "https://{0}/adfs/.well-known/webfinger?rel={1}&resource={2}", - drsResponse.IdentityProviderService.PassiveAuthEndpoint.Host, - DefaultRealm, resource); - - HttpResponse httpResponse = - await HttpRequest.SendGetAsync(new Uri(webfingerUrl), null, requestContext).ConfigureAwait(false); - - if (httpResponse.StatusCode != HttpStatusCode.OK) - { - throw new MsalServiceException("invalid_authority", "authority validation failed."); - } - - AdfsWebFingerResponse wfr = OAuth2Client.CreateResponse(httpResponse, requestContext, - false); - if ( - wfr.Links.FirstOrDefault( - a => - (a.Rel.Equals(DefaultRealm, StringComparison.OrdinalIgnoreCase) && - a.Href.Equals(resource, StringComparison.OrdinalIgnoreCase))) == null) - { - throw new MsalException("invalid_authority"); - } - } - - return GetDefaultOpenIdConfigurationEndpoint(); - } - - protected override string GetDefaultOpenIdConfigurationEndpoint() - { - return CanonicalAuthority + ".well-known/openid-configuration"; - } - - protected override void AddToValidatedAuthorities(string userPrincipalName) - { - AdfsAuthority authorityInstance = this; - if (ValidatedAuthorities.ContainsKey(CanonicalAuthority)) - { - authorityInstance = (AdfsAuthority) ValidatedAuthorities[CanonicalAuthority]; - } - - authorityInstance._validForDomainsList.Add(GetDomainFromUpn(userPrincipalName)); - ValidatedAuthorities[CanonicalAuthority] = authorityInstance; - } - - private async Task GetMetadataFromEnrollmentServerAsync(string userPrincipalName, - RequestContext requestContext) - { - try - { - //attempt to connect to on-premise enrollment server first. - return await QueryEnrollmentServerEndpointAsync(string.Format(CultureInfo.InvariantCulture, - "https://enterpriseregistration.{0}/enrollmentserver/contract", - GetDomainFromUpn(userPrincipalName)), requestContext).ConfigureAwait(false); - } - catch (Exception exc) - { - const string msg = "On-Premise ADFS enrollment server endpoint lookup failed. Error - "; - string noPiiMsg = exc.GetPiiScrubbedDetails(); - requestContext.Logger.Info(msg + noPiiMsg); - requestContext.Logger.InfoPii(msg + exc); - } - - return await QueryEnrollmentServerEndpointAsync(string.Format(CultureInfo.InvariantCulture, - "https://enterpriseregistration.windows.net/{0}/enrollmentserver/contract", - GetDomainFromUpn(userPrincipalName)), requestContext).ConfigureAwait(false); - } - - private async Task QueryEnrollmentServerEndpointAsync(string endpoint, RequestContext requestContext) - { - OAuth2Client client = new OAuth2Client(); - client.AddQueryParameter("api-version", "1.0"); - return await client.ExecuteRequestAsync(new Uri(endpoint), HttpMethod.Get, requestContext).ConfigureAwait(false); - } - - private string GetDomainFromUpn(string upn) - { - if (!upn.Contains("@")) - { - throw new ArgumentException("userPrincipalName does not contain @ character."); - } - - return upn.Split('@')[1]; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta deleted file mode 100644 index fb3feb5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsAuthority.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d2829a6bb815554ca85e6f54a4ee0ba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs deleted file mode 100644 index 2d3ddc1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs +++ /dev/null @@ -1,61 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted free of charge to any person obtaining a copy -// of this software and associated documentation files(the "Software") to deal -// in the Software without restriction including without limitation the rights -// to use copy modify merge publish distribute sublicense and / or sell -// copies of the Software and to permit persons to whom the Software is -// furnished to do so subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR -// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER -// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Collections.Generic; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class AdfsWebFingerResponseClaim : OAuth2ResponseBaseClaim - { - public const string Subject = "subject"; - public const string Links = "links"; - public const string Rel = "rel"; - public const string Href = "href"; - } - - [DataContract(Name = AdfsWebFingerResponseClaim.Links)] - internal class LinksList - { - [DataMember(Name = AdfsWebFingerResponseClaim.Rel, IsRequired = false)] - public string Rel { get; set; } - - [DataMember(Name = AdfsWebFingerResponseClaim.Href, IsRequired = false)] - public string Href { get; set; } - } - - [DataContract] - internal class AdfsWebFingerResponse : OAuth2ResponseBase - { - [DataMember(Name = AdfsWebFingerResponseClaim.Subject, IsRequired = false)] - public string Subject { get; set; } - - [DataMember(Name = AdfsWebFingerResponseClaim.Links, IsRequired = false)] - public List Links { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta deleted file mode 100644 index 8153583..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/AdfsWebFingerResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a14f36ec8baa0484cb0855b8885b455c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs deleted file mode 100644 index 21126be..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs +++ /dev/null @@ -1,259 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal enum AuthorityType - { - Aad, - Adfs, - B2C - } - - internal abstract class Authority - { - private static readonly HashSet TenantlessTenantNames = - new HashSet(new[] {"common", "organizations"}); - private bool _resolved; - - internal static readonly ConcurrentDictionary ValidatedAuthorities = - new ConcurrentDictionary(); - - private static readonly string RequiredAuthorityUriScheme = "https"; - - protected abstract Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext); - - public static Authority CreateAuthority(string authority, bool validateAuthority) - { - return CreateInstance(authority, validateAuthority); - } - - protected Authority(string authority, bool validateAuthority) - { - UriBuilder authorityUri = new UriBuilder(authority); - Host = authorityUri.Host; - string[] pathSegments = authorityUri.Uri.AbsolutePath.Substring(1).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - CanonicalAuthority = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", authorityUri.Uri.Authority, - pathSegments[0]); - ValidateAuthority = validateAuthority; - } - - public AuthorityType AuthorityType { get; set; } - - public string CanonicalAuthority { get; set; } - - public bool ValidateAuthority { get; set; } - - public bool IsTenantless { get; set; } - - public string AuthorizationEndpoint { get; set; } - - public string TokenEndpoint { get; set; } - - public string EndSessionEndpoint { get; set; } - - public string SelfSignedJwtAudience { get; set; } - - public string Host { get; set; } - - public static void ValidateAsUri(string authority) - { - if (string.IsNullOrWhiteSpace(authority)) - { - throw new ArgumentNullException(nameof(authority)); - } - - if (!Uri.IsWellFormedUriString(authority, UriKind.Absolute)) - { - throw new ArgumentException(MsalErrorMessage.AuthorityInvalidUriFormat, nameof(authority)); - } - - var authorityUri = new Uri(authority); - if (authorityUri.Scheme != Authority.RequiredAuthorityUriScheme) - { - throw new ArgumentException(MsalErrorMessage.AuthorityUriInsecure, nameof(authority)); - } - - string path = authorityUri.AbsolutePath.Substring(1); - if (string.IsNullOrWhiteSpace(path)) - { - throw new ArgumentException(MsalErrorMessage.AuthorityUriInvalidPath, nameof(authority)); - } - - string[] pathSegments = authorityUri.AbsolutePath.Substring(1).Split('/'); - if (pathSegments == null || pathSegments.Length == 0) - { - throw new ArgumentException(MsalErrorMessage.AuthorityUriInvalidPath); - } - } - - private static Authority CreateInstance(string authority, bool validateAuthority) - { - authority = CanonicalizeUri(authority); - ValidateAsUri(authority); - string[] pathSegments = new Uri(authority).AbsolutePath.Substring(1).Split('/'); - bool isAdfsAuthority = string.Compare(pathSegments[0], "adfs", StringComparison.OrdinalIgnoreCase) == 0; - bool isB2CAuthority = string.Compare(pathSegments[0], B2CAuthority.Prefix, StringComparison.OrdinalIgnoreCase) == 0; - - if (isAdfsAuthority) - { - throw new MsalException(MsalError.InvalidAuthorityType, "ADFS is not a supported authority"); - } - - if (isB2CAuthority) - { - return new B2CAuthority(authority, validateAuthority); - } - - return new AadAuthority(authority, validateAuthority); - } - - public async Task ResolveEndpointsAsync(string userPrincipalName, RequestContext requestContext) - { - var msg = "Resolving authority endpoints... Already resolved? - " + _resolved; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - - if (!_resolved) - { - var authorityUri = new Uri(CanonicalAuthority); - string host = authorityUri.Authority; - string path = authorityUri.AbsolutePath.Substring(1); - string tenant = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal)); - IsTenantless = TenantlessTenantNames.Contains(tenant.ToLowerInvariant()); - // create log message - msg = "Is Authority tenantless? - " + IsTenantless; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - - if (ExistsInValidatedAuthorityCache(userPrincipalName)) - { - msg = "Authority found in validated authority cache"; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - Authority authority = ValidatedAuthorities[CanonicalAuthority]; - AuthorityType = authority.AuthorityType; - CanonicalAuthority = authority.CanonicalAuthority; - ValidateAuthority = authority.ValidateAuthority; - IsTenantless = authority.IsTenantless; - AuthorizationEndpoint = authority.AuthorizationEndpoint; - TokenEndpoint = authority.TokenEndpoint; - EndSessionEndpoint = authority.EndSessionEndpoint; - SelfSignedJwtAudience = authority.SelfSignedJwtAudience; - - return; - } - - string openIdConfigurationEndpoint = - await - GetOpenIdConfigurationEndpointAsync(userPrincipalName, requestContext) - .ConfigureAwait(false); - - //discover endpoints via openid-configuration - TenantDiscoveryResponse edr = - await DiscoverEndpointsAsync(openIdConfigurationEndpoint, requestContext).ConfigureAwait(false); - - if (string.IsNullOrEmpty(edr.AuthorizationEndpoint)) - { - throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, - "Authorize endpoint was not found in the openid configuration"); - } - - if (string.IsNullOrEmpty(edr.TokenEndpoint)) - { - throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, - "Token endpoint was not found in the openid configuration"); - } - - if (string.IsNullOrEmpty(edr.Issuer)) - { - throw new MsalClientException(MsalClientException.TenantDiscoveryFailedError, - "Issuer was not found in the openid configuration"); - } - - AuthorizationEndpoint = edr.AuthorizationEndpoint.Replace("{tenant}", tenant); - TokenEndpoint = edr.TokenEndpoint.Replace("{tenant}", tenant); - SelfSignedJwtAudience = edr.Issuer.Replace("{tenant}", tenant); - - _resolved = true; - - AddToValidatedAuthorities(userPrincipalName); - } - } - - protected abstract bool ExistsInValidatedAuthorityCache(string userPrincipalName); - - protected abstract void AddToValidatedAuthorities(string userPrincipalName); - - protected abstract string GetDefaultOpenIdConfigurationEndpoint(); - - private async Task DiscoverEndpointsAsync(string openIdConfigurationEndpoint, - RequestContext requestContext) - { - OAuth2Client client = new OAuth2Client(); - return - await - client.ExecuteRequestAsync(new Uri(openIdConfigurationEndpoint), - HttpMethod.Get, requestContext).ConfigureAwait(false); - } - - public static string UpdateTenantId(string authority, string replacementTenantId) - { - Uri authUri = new Uri(authority); - string[] pathSegments = authUri.AbsolutePath.Substring(1).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - if (TenantlessTenantNames.Contains(pathSegments[0]) && !string.IsNullOrWhiteSpace(replacementTenantId)) - { - return string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", authUri.Authority, - replacementTenantId); - } - - return authority; - } - - public static string CanonicalizeUri(string uri) - { - if (!string.IsNullOrWhiteSpace(uri) && !uri.EndsWith("/", StringComparison.OrdinalIgnoreCase)) - { - uri = uri + "/"; - } - - return uri.ToLowerInvariant(); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta deleted file mode 100644 index e148118..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/Authority.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5108c560a1062e64fb75bbd32a3a5b78 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs deleted file mode 100644 index 882831c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted free of charge to any person obtaining a copy -// of this software and associated documentation files(the "Software") to deal -// in the Software without restriction including without limitation the rights -// to use copy modify merge publish distribute sublicense and / or sell -// copies of the Software and to permit persons to whom the Software is -// furnished to do so subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR -// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER -// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class B2CAuthority : AadAuthority - { - public const string Prefix = "tfp"; // The http path of B2C authority looks like "/tfp//..." - - public B2CAuthority(string authority, bool validateAuthority) : base(authority, validateAuthority) - { - Uri authorityUri = new Uri(authority); - string[] pathSegments = authorityUri.AbsolutePath.Substring(1).Split(new [] { '/'}, StringSplitOptions.RemoveEmptyEntries); - if (pathSegments.Length < 3) - { - throw new ArgumentException(MsalErrorMessage.B2cAuthorityUriInvalidPath); - } - - CanonicalAuthority = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/{2}/{3}/", authorityUri.Authority, - pathSegments[0], pathSegments[1], pathSegments[2]); - AuthorityType = AuthorityType.B2C; - UpdateCanonicalAuthority(); - } - - protected override async Task GetOpenIdConfigurationEndpointAsync(string userPrincipalName, RequestContext requestContext) - { - if (ValidateAuthority && !IsInTrustedHostList(new Uri(CanonicalAuthority).Host)) - { - throw new ArgumentException(MsalErrorMessage.UnsupportedAuthorityValidation); - } - - return await Task.Run(() => GetDefaultOpenIdConfigurationEndpoint()).ConfigureAwait(false); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta deleted file mode 100644 index 538f738..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/B2CAuthority.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7f6fe656f52b52344998412c59e44f3f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs deleted file mode 100644 index 6cb78c0..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs +++ /dev/null @@ -1,53 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted free of charge to any person obtaining a copy -// of this software and associated documentation files(the "Software") to deal -// in the Software without restriction including without limitation the rights -// to use copy modify merge publish distribute sublicense and / or sell -// copies of the Software and to permit persons to whom the Software is -// furnished to do so subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR -// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER -// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class DrsMetadataResponseClaim : OAuth2ResponseBaseClaim - { - public const string PassiveAuthEndpoint = "PassiveAuthEndpoint"; - public const string IdentityProviderService = "IdentityProviderService"; - } - - [DataContract] - internal class IdentityProviderService - { - [DataMember(Name = DrsMetadataResponseClaim.PassiveAuthEndpoint, IsRequired = false)] - public Uri PassiveAuthEndpoint { get; set; } - } - - [DataContract] - internal class DrsMetadataResponse : OAuth2ResponseBase - { - [DataMember(Name = DrsMetadataResponseClaim.IdentityProviderService, IsRequired = false)] - public IdentityProviderService IdentityProviderService { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta deleted file mode 100644 index 9deceb1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/DrsMetadataResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 000543523d525a74fa324d826d6ba849 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs deleted file mode 100644 index ceca1ab..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs +++ /dev/null @@ -1,39 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted free of charge to any person obtaining a copy -// of this software and associated documentation files(the "Software") to deal -// in the Software without restriction including without limitation the rights -// to use copy modify merge publish distribute sublicense and / or sell -// copies of the Software and to permit persons to whom the Software is -// furnished to do so subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR -// IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM DAMAGES OR OTHER -// LIABILITY WHETHER IN AN ACTION OF CONTRACT TORT OR OTHERWISE ARISING FROM -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - [DataContract] - internal sealed class InstanceDiscoveryResponse : OAuth2ResponseBase - { - [DataMember(Name = "tenant_discovery_endpoint", IsRequired = false)] - public string TenantDiscoveryEndpoint { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta deleted file mode 100644 index 57d322e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/InstanceDiscoveryResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 246b00acac8019048b665d5c85c1398d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs deleted file mode 100644 index 66e5a46..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Runtime.Serialization; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Instance -{ - internal class TenantDiscoveryResponseClaim : OAuth2ResponseBaseClaim - { - public const string AuthorizationEndpoint = "authorization_endpoint"; - public const string TokenEndpoint = "token_endpoint"; - public const string Issuer = "issuer"; - } - - [DataContract] - internal class TenantDiscoveryResponse : OAuth2ResponseBase - { - [DataMember(Name = TenantDiscoveryResponseClaim.AuthorizationEndpoint, IsRequired = false)] - public string AuthorizationEndpoint { get; set; } - - [DataMember(Name = TenantDiscoveryResponseClaim.TokenEndpoint, IsRequired = false)] - public string TokenEndpoint { get; set; } - - [DataMember(Name = TenantDiscoveryResponseClaim.Issuer, IsRequired = false)] - public string Issuer { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta deleted file mode 100644 index 89eab0a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Instance/TenantDiscoveryResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ac3dcddedd169de4fa94502ec91dfec0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta deleted file mode 100644 index a24a683..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0d3b45f3e6ccd8449baa6023e9d6f7e2 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs deleted file mode 100644 index 278ce1e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs +++ /dev/null @@ -1,41 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client.Internal.Interfaces -{ - internal interface IWebUI - { - RequestContext RequestContext { get; set; } - - Task AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext); - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta deleted file mode 100644 index 6121991..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e687b74e9071fcd49af34347772c3f65 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs deleted file mode 100644 index 1aa1067..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs +++ /dev/null @@ -1,34 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Identity.Client.Internal.Interfaces -{ - internal interface IWebUIFactory - { - IWebUI CreateAuthenticationDialog(UIParent parent, RequestContext requestContext); - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta deleted file mode 100644 index 7cfaf0c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Interfaces/IWebUIFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f026f8960a58eca4a8057a7269371f79 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs deleted file mode 100644 index af48155..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs +++ /dev/null @@ -1,73 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.IO; -using System.Runtime.Serialization.Json; -using System.Text; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class JsonHelper - { - internal static string SerializeToJson(T toEncode) - { - using (MemoryStream stream = new MemoryStream()) - { - DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof (T)); - ser.WriteObject(stream, toEncode); - return Encoding.UTF8.GetString(stream.ToArray(), 0, (int) stream.Position); - } - } - - internal static T DeserializeFromJson(string json) - { - if (string.IsNullOrEmpty(json)) - { - return default(T); - } - - return DeserializeFromJson(json.ToByteArray()); - } - - internal static T DeserializeFromJson(byte[] jsonByteArray) - { - if (jsonByteArray == null || jsonByteArray.Length == 0) - { - return default(T); - } - - T response; - DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (T)); - using (MemoryStream stream = new MemoryStream(jsonByteArray)) - { - response = ((T) serializer.ReadObject(stream)); - } - - return response; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta deleted file mode 100644 index 6c4b793..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/JsonHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9d47cbe545f070c44b7cd993621425e9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs deleted file mode 100644 index 1b61613..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs +++ /dev/null @@ -1,86 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Identity.Client.Internal -{ - /// - /// Error code returned as a property in MsalException - /// - internal static class MsalError - { - /// - /// Authentication failed. - /// - public const string AuthenticationFailed = "authentication_failed"; - - - /// - /// Authority validation failed. - /// - public const string AuthorityValidationFailed = "authority_validation_failed"; - - /// - /// Invalid owner window type. - /// - public const string InvalidOwnerWindowType = "invalid_owner_window_type"; - - /// - /// Invalid authority type. - /// - public const string InvalidAuthorityType = "invalid_authority_type"; - - /// - /// Invalid service URL. - /// - public const string InvalidServiceUrl = "invalid_service_url"; - - /// - /// Encoded token too long. - /// - public const string EncodedTokenTooLong = "encoded_token_too_long"; - - /// - /// No data from STS. - /// - public const string NoDataFromSts = "no_data_from_sts"; - - /// - /// User Mismatch. - /// - public const string UserMismatch = "user_mismatch"; - - /// - /// Failed to refresh token. - /// - public const string FailedToRefreshToken = "failed_to_refresh_token"; - - /// - /// RedirectUri validation failed. - /// - public const string RedirectUriValidationFailed = "redirect_uri_validation_failed"; - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta deleted file mode 100644 index 63d388c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalError.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2cbe2fa1b8d281a4a8e47384b8922042 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs deleted file mode 100644 index e7f104e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs +++ /dev/null @@ -1,378 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class MsalHelpers - { - public static string ToStringInvariant(this int val) - { - return val.ToString(CultureInfo.InvariantCulture); - } - - public static string ToStringInvariant(this long val) - { - return val.ToString(CultureInfo.InvariantCulture); - } - - public static bool ScopeContains(this SortedSet scopes, SortedSet otherScope) - { - foreach (string otherString in otherScope) - { - if (!scopes.Contains(otherString, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - return true; - } - - public static bool ScopeIntersects(this SortedSet scopes, SortedSet otherScope) - { - return scopes.Overlaps(otherScope); - } - - internal static string[] AsArray(this SortedSet setOfStrings) - { - return setOfStrings?.ToArray(); - } - - internal static string AsSingleString(this IEnumerable input) - { - if (IsNullOrEmpty(input)) - { - return string.Empty; - } - - return string.Join(" ", input); - } - - internal static SortedSet AsSet(this string singleString) - { - if (string.IsNullOrEmpty(singleString)) - { - return new SortedSet(); - } - - return new SortedSet(singleString.Split(new[] { " " }, StringSplitOptions.None)); - } - - internal static string[] AsArray(this string singleString) - { - if (string.IsNullOrWhiteSpace(singleString)) - { - return new string[] { }; - } - - return singleString.Split(new[] { " " }, StringSplitOptions.None); - } - - internal static SortedSet CreateSetFromEnumerable(this IEnumerable input) - { - if (input == null || !input.Any()) - { - return new SortedSet(); - } - return new SortedSet(input); - } - - internal static bool IsNullOrEmpty(IEnumerable input) - { - return input == null || !input.Any(); - } - - internal static string ByteArrayToString(byte[] input) - { - if (input == null || input.Length == 0) - { - return null; - } - - return Encoding.UTF8.GetString(input, 0, input.Length); - } - - public static DateTime UnixTimestampToDateTime(double unixTimestamp) - { - DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - dateTime = dateTime.AddSeconds(unixTimestamp).ToUniversalTime(); - return dateTime; - } - - public static long DateTimeToUnixTimestamp(DateTimeOffset dateTimeOffset) - { - DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - long unixTimestamp = (long)dateTimeOffset.Subtract(dateTime).TotalSeconds; - return unixTimestamp; - } - - public static long DateTimeToUnixTimestampMilliseconds(DateTimeOffset dateTimeOffset) - { - DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - long unixTimestamp = (long)dateTimeOffset.Subtract(dateTime).TotalMilliseconds; - return unixTimestamp; - } - - public static string CreateString(byte[] bytes) - { - return Encoding.UTF8.GetString(bytes, 0, bytes.Length); - } - - public static string UrlEncode(string message) - { - if (string.IsNullOrEmpty(message)) - { - return message; - } - - message = Uri.EscapeDataString(message); - message = message.Replace("%20", "+"); - - return message; - } - - public static string UrlDecode(string message) - { - if (string.IsNullOrEmpty(message)) - { - return message; - } - - message = message.Replace("+", "%20"); - message = Uri.UnescapeDataString(message); - - return message; - } - - public static void AddKeyValueString(StringBuilder messageBuilder, string key, string value) - { - AddKeyValueString(messageBuilder, key, value.ToCharArray()); - } - - public static string ToQueryParameter(this IDictionary input) - { - StringBuilder builder = new StringBuilder(); - - if (input.Count > 0) - { - foreach (var key in input.Keys) - { - builder.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", key, UrlEncode(input[key])); - } - - if (builder.Length > 0) - { - builder.Remove(builder.Length - 1, 1); - } - } - - return builder.ToString(); - } - - public static Dictionary ParseKeyValueList(string input, char delimiter, bool urlDecode, - bool lowercaseKeys, - RequestContext requestContext) - { - var response = new Dictionary(); - - List queryPairs = SplitWithQuotes(input, delimiter); - - foreach (string queryPair in queryPairs) - { - List pair = SplitWithQuotes(queryPair, '='); - - if (pair.Count == 2 && !string.IsNullOrWhiteSpace(pair[0]) && !string.IsNullOrWhiteSpace(pair[1])) - { - string key = pair[0]; - string value = pair[1]; - - // Url decoding is needed for parsing OAuth response, but not for parsing WWW-Authenticate header in 401 challenge - if (urlDecode) - { - key = UrlDecode(key); - value = UrlDecode(value); - } - - if (lowercaseKeys) - { - key = key.Trim().ToLowerInvariant(); - } - - value = value.Trim().Trim('\"').Trim(); - - if (response.ContainsKey(key)) - { - var msg = string.Format(CultureInfo.InvariantCulture, - "Key/value pair list contains redundant key '{0}'.", key); - requestContext?.Logger.Warning(msg); - requestContext?.Logger.WarningPii(msg); - } - - response[key] = value; - } - } - - return response; - } - - public static Dictionary ParseKeyValueList(string input, char delimiter, bool urlDecode, - RequestContext requestContext) - { - return ParseKeyValueList(input, delimiter, urlDecode, true, requestContext); - } - - public static byte[] ToByteArray(this String stringInput) - { - return ToByteArray(new StringBuilder(stringInput)); - } - - public static byte[] ToByteArray(this StringBuilder stringBuilder) - { - if (stringBuilder == null) - { - return null; - } - - UTF8Encoding encoding = new UTF8Encoding(); - var messageChars = new char[stringBuilder.Length]; - - try - { - stringBuilder.CopyTo(0, messageChars, 0, stringBuilder.Length); - return encoding.GetBytes(messageChars); - } - finally - { - messageChars.SecureClear(); - } - } - - public static void SecureClear(this StringBuilder stringBuilder) - { - if (stringBuilder != null) - { - for (int i = 0; i < stringBuilder.Length; i++) - { - stringBuilder[i] = '\0'; - } - - stringBuilder.Length = 0; - } - } - - public static void SecureClear(this byte[] bytes) - { - if (bytes != null) - { - for (int i = 0; i < bytes.Length; i++) - { - bytes[i] = 0; - } - } - } - - public static void SecureClear(this char[] chars) - { - if (chars != null) - { - for (int i = 0; i < chars.Length; i++) - { - chars[i] = '\0'; - } - } - } - - internal static List SplitWithQuotes(string input, char delimiter) - { - List items = new List(); - - if (string.IsNullOrWhiteSpace(input)) - { - return items; - } - - int startIndex = 0; - bool insideString = false; - string item; - for (int i = 0; i < input.Length; i++) - { - if (input[i] == delimiter && !insideString) - { - item = input.Substring(startIndex, i - startIndex); - if (!string.IsNullOrWhiteSpace(item.Trim())) - { - items.Add(item); - } - - startIndex = i + 1; - } - else if (input[i] == '"') - { - insideString = !insideString; - } - } - - item = input.Substring(startIndex); - if (!string.IsNullOrWhiteSpace(item.Trim())) - { - items.Add(item); - } - - return items; - } - - public static void AppendQueryParameters(this UriBuilder builder, string queryParams) - { - if (builder == null || string.IsNullOrEmpty(queryParams)) - { - return; - } - - if (builder.Query.Length > 1) - { - builder.Query = builder.Query.Substring(1) + "&" + queryParams; - } - else - { - builder.Query = queryParams; - } - } - - private static void AddKeyValueString(StringBuilder messageBuilder, string key, char[] value) - { - string delimiter = (messageBuilder.Length == 0) ? string.Empty : "&"; - messageBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}=", delimiter, key); - messageBuilder.Append(value); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta deleted file mode 100644 index 72b53fc..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalHelpers.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a27456c62b04b694989d038f39bc113e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs deleted file mode 100644 index dee41b1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs +++ /dev/null @@ -1,125 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text.RegularExpressions; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class MsalIdParameter - { - /// - /// MSAL Flavor: .NET or WinRT - /// - public const string Product = "x-client-SKU"; - - /// - /// MSAL assembly version - /// - public const string Version = "x-client-Ver"; - - /// - /// CPU platform with x86, x64 or ARM as value - /// - public const string CpuPlatform = "x-client-CPU"; - - /// - /// Version of the operating system. This will not be sent on WinRT - /// - public const string OS = "x-client-OS"; - - /// - /// Device model. This will not be sent on .NET - /// - public const string DeviceModel = "x-client-DM"; - } - - /// - /// This class adds additional query parameters or headers to the requests sent to STS. This can help us in - /// collecting statistics and potentially on diagnostics. - /// - internal static class MsalIdHelper - { - private static readonly Regex MsalVersionRegex = new Regex(@"Version=[\d]+.[\d+]+.[\d]+.[\d]+", RegexOptions.CultureInvariant); - - public static IDictionary GetMsalIdParameters() - { - var parameters = new Dictionary(); - - parameters[MsalIdParameter.Product] = PlatformPlugin.PlatformInformation.GetProductName(); - parameters[MsalIdParameter.Version] = GetMsalVersion(); - - var processorInofrmation = PlatformPlugin.PlatformInformation.GetProcessorArchitecture(); - if (processorInofrmation != null) - { - parameters[MsalIdParameter.CpuPlatform] = processorInofrmation; - } - - var osInformation = PlatformPlugin.PlatformInformation.GetOperatingSystem(); - if (osInformation != null) - { - parameters[MsalIdParameter.OS] = osInformation; - } - - var deviceInformation = PlatformPlugin.PlatformInformation.GetDeviceModel(); - if (deviceInformation != null) - { - parameters[MsalIdParameter.DeviceModel] = deviceInformation; - } - - return parameters; - } - - public static string GetMsalVersion() - { - string fullVersion = typeof(MsalIdHelper).GetTypeInfo().Assembly.FullName; - - Match match = MsalVersionRegex.Match(fullVersion); - if (match.Success) - { - string[] version = match.Groups[0].Value.Split(new[] {'='}, StringSplitOptions.None); - return version[1]; - } - - return null; - } - - public static string GetAssemblyFileVersion() - { - return PlatformPlugin.PlatformInformation.GetAssemblyFileVersionAttribute(); - } - - public static string GetAssemblyInformationalVersion() - { - AssemblyInformationalVersionAttribute attribute = - typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute(); - return (attribute != null) ? attribute.InformationalVersion : string.Empty; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta deleted file mode 100644 index 1442f0e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/MsalIdHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5bc29bf09a4a5404e917b495da71fb5e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta deleted file mode 100644 index 1c47a90..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a70ef007086b44447af760be8b2a93c6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs deleted file mode 100644 index 4778d83..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs +++ /dev/null @@ -1,198 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.Http; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client.Internal.OAuth2 -{ - internal class OAuth2Client - { - private readonly Dictionary _bodyParameters = new Dictionary(); - - private readonly Dictionary _headers = - new Dictionary(MsalIdHelper.GetMsalIdParameters()); - - private readonly Dictionary _queryParameters = new Dictionary(); - - public void AddQueryParameter(string key, string value) - { - _queryParameters[key] = value; - } - - public void AddHeader(string key, string value) - { - _headers[key] = value; - } - - public void AddBodyParameter(string key, string value) - { - _bodyParameters[key] = value; - } - - public async Task GetOpenIdConfigurationAsync(Uri endPoint, RequestContext requestContext) - { - return await ExecuteRequestAsync(endPoint, HttpMethod.Get, requestContext).ConfigureAwait(false); - } - - public async Task DiscoverAadInstanceAsync(Uri endPoint, RequestContext requestContext) - { - return await ExecuteRequestAsync(endPoint, HttpMethod.Get, requestContext).ConfigureAwait(false); - } - - public async Task GetTokenAsync(Uri endPoint, RequestContext requestContext) - { - return await ExecuteRequestAsync(endPoint, HttpMethod.Post, requestContext).ConfigureAwait(false); - } - - internal async Task ExecuteRequestAsync(Uri endPoint, HttpMethod method, RequestContext requestContext) - { - bool addCorrelationId = (requestContext != null && !string.IsNullOrEmpty(requestContext.CorrelationId)); - if (addCorrelationId) - { - _headers.Add(OAuth2Header.CorrelationId, requestContext.CorrelationId); - _headers.Add(OAuth2Header.RequestCorrelationIdInResponse, "true"); - } - - HttpResponse response = null; - Uri endpointUri = CreateFullEndpointUri(endPoint); - var httpEvent = new HttpEvent(){HttpPath = endpointUri, QueryParams = endpointUri.Query}; - Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, httpEvent); - try - { - if (method == HttpMethod.Post) - { - response = await HttpRequest.SendPostAsync(endpointUri, _headers, _bodyParameters, requestContext).ConfigureAwait(false); - } - else - { - response = await HttpRequest.SendGetAsync(endpointUri, _headers, requestContext).ConfigureAwait(false); - } - - httpEvent.HttpResponseStatus = (int) response.StatusCode; - httpEvent.UserAgent = response.UserAgent; - if (response.StatusCode != HttpStatusCode.OK) - { - httpEvent.OauthErrorCode = JsonHelper.DeserializeFromJson(response.Body).Error; - } - } - finally - { - Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, httpEvent); - } - - return CreateResponse(response, requestContext, addCorrelationId); - } - - public static T CreateResponse(HttpResponse response, RequestContext requestContext, bool addCorrelationId) - { - if (response.StatusCode != HttpStatusCode.OK) - { - CreateErrorResponse(response, requestContext); - } - - if (addCorrelationId) - { - VerifyCorrelationIdHeaderInReponse(response.Headers, requestContext); - } - - return JsonHelper.DeserializeFromJson(response.Body); - } - - public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext) - { - MsalServiceException serviceEx; - try - { - TokenResponse tokenResponse = JsonHelper.DeserializeFromJson(response.Body); - - if (MsalUiRequiredException.InvalidGrantError.Equals(tokenResponse.Error, - StringComparison.OrdinalIgnoreCase)) - { - throw new MsalUiRequiredException(MsalUiRequiredException.InvalidGrantError, - tokenResponse.ErrorDescription) - { - Claims = tokenResponse.Claims - }; - } - - serviceEx = new MsalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription, (int)response.StatusCode, tokenResponse.Claims, null) - { - ResponseBody = response.Body - }; - } - catch (SerializationException) - { - serviceEx = new MsalServiceException(MsalException.UnknownError, response.Body, (int)response.StatusCode); - } - - requestContext.Logger.Error(serviceEx); - requestContext.Logger.ErrorPii(serviceEx); - throw serviceEx; - } - - internal Uri CreateFullEndpointUri(Uri endPoint) - { - UriBuilder endpointUri = new UriBuilder(endPoint); - string extraQp = _queryParameters.ToQueryParameter(); - endpointUri.AppendQueryParameters(extraQp); - - return endpointUri.Uri; - } - - private static void VerifyCorrelationIdHeaderInReponse(Dictionary headers, RequestContext requestContext) - { - foreach (string reponseHeaderKey in headers.Keys) - { - string trimmedKey = reponseHeaderKey.Trim(); - if (string.Compare(trimmedKey, OAuth2Header.CorrelationId, StringComparison.OrdinalIgnoreCase) == 0) - { - string correlationIdHeader = headers[trimmedKey].Trim(); - if (!string.Equals(correlationIdHeader, requestContext.CorrelationId)) - { - requestContext.Logger.Warning("Returned correlation id does not match the sent correlation id"); - requestContext.Logger.WarningPii(string.Format(CultureInfo.InvariantCulture, - "Returned correlation id '{0}' does not match the sent correlation id '{1}'", - correlationIdHeader, requestContext.CorrelationId)); - } - - break; - } - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta deleted file mode 100644 index 3b7465e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2Client.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 59e69fa498f9e6c4cb10f4a461c727a8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs deleted file mode 100644 index 362ff60..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs +++ /dev/null @@ -1,59 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Runtime.Serialization; - -namespace Microsoft.Identity.Client.Internal.OAuth2 -{ - internal class OAuth2ResponseBaseClaim - { - public const string Claims = "claims"; - public const string Error = "error"; - public const string ErrorDescription = "error_description"; - public const string ErrorCodes = "error_codes"; - public const string CorrelationId = "correlation_id"; - } - - [DataContract] - internal class OAuth2ResponseBase - { - [DataMember(Name = OAuth2ResponseBaseClaim.Error, IsRequired = false)] - public string Error { get; set; } - - [DataMember(Name = OAuth2ResponseBaseClaim.ErrorDescription, IsRequired = false)] - public string ErrorDescription { get; set; } - - [DataMember(Name = OAuth2ResponseBaseClaim.ErrorCodes, IsRequired = false)] - public string[] ErrorCodes { get; set; } - - [DataMember(Name = OAuth2ResponseBaseClaim.CorrelationId, IsRequired = false)] - public string CorrelationId { get; set; } - - [DataMember(Name = OAuth2ResponseBaseClaim.Claims, IsRequired = false)] - public string Claims { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta deleted file mode 100644 index a7a8521..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuth2ResponseBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8e49c049980d8c41a833fc6b656bf7e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs deleted file mode 100644 index 0e40e4f..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs +++ /dev/null @@ -1,114 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Identity.Client.Internal.OAuth2 -{ - internal class OAuth2Parameter - { - public const string ResponseType = "response_type"; - public const string GrantType = "grant_type"; - public const string ClientId = "client_id"; - public const string ClientSecret = "client_secret"; - public const string ClientAssertion = "client_assertion"; - public const string ClientAssertionType = "client_assertion_type"; - public const string RefreshToken = "refresh_token"; - public const string RedirectUri = "redirect_uri"; - public const string Resource = "resource"; - public const string Code = "code"; - public const string Scope = "scope"; - public const string Assertion = "assertion"; - public const string RequestedTokenUse = "requested_token_use"; - public const string Username = "username"; - public const string Password = "password"; - public const string LoginHint = "login_hint"; // login_hint is not standard oauth2 parameter - public const string CorrelationId = OAuth2Header.CorrelationId; - public const string State = "state"; - - public const string CodeChallengeMethod = "code_challenge_method"; - public const string CodeChallenge = "code_challenge"; - public const string CodeVerifier = "code_verifier"; - // correlation id is not standard oauth2 parameter - public const string LoginReq = "login_req"; - public const string DomainReq = "domain_req"; - - public const string Prompt = "prompt"; // prompt is not standard oauth2 parameter - public const string ClientInfo = "client_info"; // restrict_to_hint is not standard oauth2 parameter - } - - internal class OAuth2GrantType - { - public const string AuthorizationCode = "authorization_code"; - public const string RefreshToken = "refresh_token"; - public const string ClientCredentials = "client_credentials"; - public const string Saml11Bearer = "urn:ietf:params:oauth:grant-type:saml1_1-bearer"; - public const string Saml20Bearer = "urn:ietf:params:oauth:grant-type:saml2-bearer"; - public const string JwtBearer = "urn:ietf:params:oauth:grant-type:jwt-bearer"; - public const string Password = "password"; - public const string DeviceCode = "device_code"; - } - - internal class OAuth2ResponseType - { - public const string Code = "code"; - } - - internal class OAuth2AssertionType - { - public const string JwtBearer = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"; - } - - internal class OAuth2RequestedTokenUse - { - public const string OnBehalfOf = "on_behalf_of"; - } - - internal class OAuth2Header - { - public const string CorrelationId = "client-request-id"; - public const string RequestCorrelationIdInResponse = "return-client-request-id"; - } - - internal class OAuth2Error - { - public const string LoginRequired = "login_required"; - } - - internal class OAuth2Value - { - public static readonly string[] ReservedScopes = {"openid", "profile", "offline_access"}; - public const string CodeChallengeMethodValue = "S256"; - } - - internal class PromptValue - { - public const string Login = "login"; - public const string RefreshSession = "refresh_session"; - // The behavior of this value is identical to prompt=none for managed users; However, for federated users, AAD - // redirects to ADFS as it cannot determine in advance whether ADFS can login user silently (e.g. via WIA) or not. - public const string AttemptNone = "attempt_none"; - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta deleted file mode 100644 index eb10838..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/OAuthConstants.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6cfcdad38081e8e4daafbb36c5183131 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs deleted file mode 100644 index b27f581..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs +++ /dev/null @@ -1,74 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Runtime.Serialization; - -namespace Microsoft.Identity.Client.Internal.OAuth2 -{ - internal class TokenResponseClaim : OAuth2ResponseBaseClaim - { - public const string Code = "code"; - public const string TokenType = "token_type"; - public const string AccessToken = "access_token"; - public const string RefreshToken = "refresh_token"; - public const string Scope = "scope"; - public const string ClientInfo = "client_info"; - public const string IdToken = "id_token"; - public const string ExpiresIn = "expires_in"; - } - - [DataContract] - internal class TokenResponse : OAuth2ResponseBase - { - [DataMember(Name = TokenResponseClaim.TokenType, IsRequired = false)] - public string TokenType { get; set; } - - [DataMember(Name = TokenResponseClaim.AccessToken, IsRequired = false)] - public string AccessToken { get; set; } - - [DataMember(Name = TokenResponseClaim.RefreshToken, IsRequired = false)] - public string RefreshToken { get; set; } - - [DataMember(Name = TokenResponseClaim.Scope, IsRequired = false)] - public string Scope { get; set; } - - [DataMember(Name = TokenResponseClaim.ClientInfo, IsRequired = false)] - public string ClientInfo { get; set; } - - [DataMember(Name = TokenResponseClaim.IdToken, IsRequired = false)] - public string IdToken { get; set; } - - [DataMember(Name = TokenResponseClaim.ExpiresIn, IsRequired = false)] - public long ExpiresIn { get; set; } - - public DateTimeOffset AccessTokenExpiresOn - { - get { return DateTime.UtcNow + TimeSpan.FromSeconds(ExpiresIn); } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta deleted file mode 100644 index d80cf2d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/OAuth2/TokenResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9ce97686a77e28e4bb7f8301304dcf1d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs deleted file mode 100644 index c92c19a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs +++ /dev/null @@ -1,83 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Threading.Tasks; - -namespace Microsoft.Identity.Client.Internal -{ - internal abstract class PlatformInformationBase - { - internal const string DefaultRedirectUri = "urn:ietf:wg:oauth:2.0:oob"; - - protected readonly RequestContext RequestContext; - protected PlatformInformationBase(RequestContext requestContext) - { - RequestContext = requestContext; - } - - public abstract string GetProductName(); - public abstract string GetEnvironmentVariable(string variable); - public abstract string GetProcessorArchitecture(); - public abstract string GetOperatingSystem(); - public abstract string GetDeviceModel(); - - public virtual string GetAssemblyFileVersionAttribute() - { - //return typeof (MsalIdHelper).GetTypeInfo().Assembly.GetCustomAttribute().Version; - return "N/A"; - } - - public virtual async Task IsUserLocalAsync(RequestContext requestContext) - { - return await Task.Factory.StartNew(() => false).ConfigureAwait(false); - } - - public virtual bool IsDomainJoined() - { - return false; - } - - public virtual void ValidateRedirectUri(Uri redirectUri, RequestContext requestContext) - { - if (redirectUri == null) - { - throw new ArgumentNullException(nameof(redirectUri)); - } - } - - public virtual string GetRedirectUriAsString(Uri redirectUri, RequestContext requestContext) - { - return redirectUri.OriginalString; - } - - public virtual string GetDefaultRedirectUri(string correlationId) - { - return DefaultRedirectUri; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta deleted file mode 100644 index 71a8e20..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformInformationBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 49988b45c72f4a549b5960af82a47f99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs deleted file mode 100644 index 69f6e74..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs +++ /dev/null @@ -1,98 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using Microsoft.Identity.Client.Internal.Interfaces; - -namespace Microsoft.Identity.Client.Internal -{ - internal static class PlatformPluginSwitch - { - static PlatformPluginSwitch() - { - DynamicallyLinkAssembly = true; - } - - public static bool DynamicallyLinkAssembly { get; set; } - } - - internal static class PlatformPlugin - { - private const string Namespace = "Microsoft.Identity.Client."; - - static PlatformPlugin() - { - if (PlatformPluginSwitch.DynamicallyLinkAssembly) - { - InitializeByAssemblyDynamicLinking(); - } - } - - public static IWebUIFactory WebUIFactory { get; set; } - - public static ILogger PlatformLogger { get; set; } - public static PlatformInformationBase PlatformInformation { get; set; } - - public static void InitializeByAssemblyDynamicLinking() - { -#if !FACADE - InjectDependecies( - (IWebUIFactory) new UI.WebUIFactory(), - (ILogger) new EventsSource.PlatformLogger(), - (PlatformInformationBase) new PlatformInformation(new RequestContext(Guid.Empty, null))); -#endif - } - - public static void InjectDependecies(IWebUIFactory webUIFactory, - ILogger platformlogger, - PlatformInformationBase platformInformation) - { - WebUIFactory = webUIFactory; - PlatformLogger = platformlogger; - PlatformInformation = platformInformation; - } - - public static void LogMessage(Logger.LogLevel logLevel, string formattedMessage) - { - switch (logLevel) - { - case Logger.LogLevel.Error: - PlatformLogger.Error(formattedMessage); - break; - case Logger.LogLevel.Warning: - PlatformLogger.Warning(formattedMessage); - break; - case Logger.LogLevel.Info: - PlatformLogger.Information(formattedMessage); - break; - case Logger.LogLevel.Verbose: - PlatformLogger.Verbose(formattedMessage); - break; - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta deleted file mode 100644 index 522ae31..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/PlatformPlugin.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c23aa7ad787e79a49af035b59670c029 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs deleted file mode 100644 index 6bdccb6..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs +++ /dev/null @@ -1,46 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client.Internal -{ - internal class RequestContext - { - public string CorrelationId { get; } - - public Logger Logger { get; set; } - - public string TelemetryRequestId { get; set; } - - public RequestContext(Guid correlationId, string component) - { - CorrelationId = correlationId.ToString(); - Logger = new Logger(correlationId, component); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta deleted file mode 100644 index 02fc0d5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/RequestContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b34633e3493394a4f965b6ef4edcf1d6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta deleted file mode 100644 index e7e7bfc..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a75e59c48a5a30e43bb68928fd7c6179 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs deleted file mode 100644 index 07fa2c8..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs +++ /dev/null @@ -1,165 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class AuthenticationRequestParameters - { - public RequestContext RequestContext { get; set; } - - public Authority Authority { get; set; } - - public string TenantUpdatedCanonicalAuthority { get; set; } - - public bool ValidateAuthority { get; set; } - - public TokenCache TokenCache { get; set; } - - public SortedSet Scope { get; set; } - - public string ClientId { get; set; } - - public string AuthorizationCode { get; set; } - - public Uri RedirectUri { get; set; } - - public string LoginHint { get; set; } - - public string ExtraQueryParameters { get; set; } - - public IUser User { get; set; } - - public ClientInfo ClientInfo { get; set; } - - public UserAssertion UserAssertion { get; set; } - - public bool IsClientCredentialRequest { get; set; } = false; - public string SliceParameters { get; set; } - -#if DESKTOP || NETSTANDARD1_3 - public ClientCredential ClientCredential { get; set; } -#endif - - public IDictionary ToParameters() - { - IDictionary parameters = new Dictionary(); -#if DESKTOP || NETSTANDARD1_3 - if (ClientCredential != null) - { - if (!string.IsNullOrEmpty(ClientCredential.Secret)) - { - parameters[OAuth2Parameter.ClientSecret] = ClientCredential.Secret; - } - else - { - if (ClientCredential.Assertion == null || ClientCredential.ValidTo != 0) - { - bool assertionNearExpiry = (ClientCredential.ValidTo <= - Jwt.JsonWebToken.ConvertToTimeT(DateTime.UtcNow + - TimeSpan.FromMinutes( - Constants - .ExpirationMarginInMinutes))); - if (assertionNearExpiry) - { - const string msg = "Client Assertion does not exist or near expiry."; - RequestContext.Logger.Info(msg); - RequestContext.Logger.InfoPii(msg); - Jwt.JsonWebToken jwtToken = new Jwt.JsonWebToken(ClientId, - Authority.SelfSignedJwtAudience); - ClientCredential.Assertion = jwtToken.Sign(ClientCredential.Certificate); - ClientCredential.ValidTo = jwtToken.Payload.ValidTo; - } - else - { - const string msg = "Reusing the unexpired Client Assertion..."; - RequestContext.Logger.Info(msg); - RequestContext.Logger.InfoPii(msg); - } - } - - parameters[OAuth2Parameter.ClientAssertionType] = OAuth2AssertionType.JwtBearer; - parameters[OAuth2Parameter.ClientAssertion] = ClientCredential.Assertion; - } - } -#endif - return parameters; - } - - public void LogState() - { - // Create Pii enabled string builder - StringBuilder builder = new StringBuilder(Environment.NewLine + "=== Request Data ===" + Environment.NewLine + - "Authority Provided? - " + (Authority != null) + Environment.NewLine); - builder.AppendLine("Client Id - " + ClientId); - builder.AppendLine("Scopes - " + Scope?.AsSingleString()); - builder.AppendLine("Redirect Uri - " + RedirectUri?.OriginalString); - builder.AppendLine("Validate Authority? - " + ValidateAuthority); - builder.AppendLine("LoginHint provided? - " + !string.IsNullOrEmpty(LoginHint)); - builder.AppendLine("User provided? - " + (User != null)); - var dict = MsalHelpers.ParseKeyValueList(ExtraQueryParameters, '&', true, RequestContext); - builder.AppendLine("Extra Query Params Keys (space separated) - " + dict.Keys.AsSingleString()); - dict = MsalHelpers.ParseKeyValueList(SliceParameters, '&', true, RequestContext); - builder.AppendLine("Slice Parameters Keys(space separated) - " + dict.Keys.AsSingleString()); -#if DESKTOP || NETSTANDARD1_3 - builder.AppendLine("Confidential Client? - " + (ClientCredential != null)); - builder.AppendLine("Client Credential Request? - " + IsClientCredentialRequest); - if (IsClientCredentialRequest) - { - builder.AppendLine("Client Certificate Provided? - " + (ClientCredential.Certificate != null)); - } -#endif - RequestContext.Logger.InfoPii(builder.ToString()); - - // Create no Pii enabled string builder - builder = new StringBuilder(Environment.NewLine + "=== Request Data ===" + Environment.NewLine + - "Authority Provided? - " + (Authority != null) + Environment.NewLine); - builder.AppendLine("Scopes - " + Scope?.AsSingleString()); - builder.AppendLine("Validate Authority? - " + ValidateAuthority); - builder.AppendLine("LoginHint provided? - " + !string.IsNullOrEmpty(LoginHint)); - builder.AppendLine("User provided? - " + (User != null)); - dict = MsalHelpers.ParseKeyValueList(ExtraQueryParameters, '&', true, RequestContext); - builder.AppendLine("Extra Query Params Keys (space separated) - " + dict.Keys.AsSingleString()); - dict = MsalHelpers.ParseKeyValueList(SliceParameters, '&', true, RequestContext); - builder.AppendLine("Slice Parameters Keys(space separated) - " + dict.Keys.AsSingleString()); -#if DESKTOP || NETSTANDARD1_3 - builder.AppendLine("Confidential Client? - " + (ClientCredential != null)); - builder.AppendLine("Client Credential Request? - " + IsClientCredentialRequest); - if (IsClientCredentialRequest) - { - builder.AppendLine("Client Certificate Provided? - " + (ClientCredential.Certificate != null)); - } -#endif - RequestContext.Logger.Info(builder.ToString()); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta deleted file mode 100644 index dcd5c26..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d03f0c3484d37534ea56b45ecb75567d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs deleted file mode 100644 index 616dc00..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs +++ /dev/null @@ -1,61 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class AuthorizationCodeRequest : RequestBase - { - public AuthorizationCodeRequest(AuthenticationRequestParameters authenticationRequestParameters) - : base(authenticationRequestParameters) - { - if (string.IsNullOrWhiteSpace(authenticationRequestParameters.AuthorizationCode)) - { - throw new ArgumentNullException(nameof(authenticationRequestParameters.AuthorizationCode)); - } - - PlatformPlugin.PlatformInformation.ValidateRedirectUri(authenticationRequestParameters.RedirectUri, - AuthenticationRequestParameters.RequestContext); - if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.RedirectUri.Fragment)) - { - throw new ArgumentException(MsalErrorMessage.RedirectUriContainsFragment, nameof(authenticationRequestParameters.RedirectUri)); - } - - LoadFromCache = false; - } - - protected override void SetAdditionalRequestParameters(OAuth2Client client) - { - client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.AuthorizationCode); - client.AddBodyParameter(OAuth2Parameter.Code, AuthenticationRequestParameters.AuthorizationCode); - client.AddBodyParameter(OAuth2Parameter.RedirectUri, - AuthenticationRequestParameters.RedirectUri.OriginalString); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta deleted file mode 100644 index 4fb3aeb..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/AuthorizationCodeRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 25bd8a7eea3224741a9016f5aad62c06 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs deleted file mode 100644 index 5a28fd5..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs +++ /dev/null @@ -1,72 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class ClientCredentialRequest : RequestBase - { - public ClientCredentialRequest(AuthenticationRequestParameters authenticationRequestParameters, bool forceRefresh) - : base(authenticationRequestParameters) - { - ForceRefresh = forceRefresh; - } - - protected override SortedSet GetDecoratedScope(SortedSet inputScope) - { - return inputScope; - } - - internal override Task PreTokenRequestAsync() - { - // look for access token in the cache first. - if (!ForceRefresh && LoadFromCache) - { - AccessTokenItem - = TokenCache.FindAccessToken(AuthenticationRequestParameters); - } - - return CompletedTask; - } - protected override async Task SendTokenRequestAsync() - { - if (AccessTokenItem == null) - { - await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); - await base.SendTokenRequestAsync().ConfigureAwait(false); - } - } - - protected override void SetAdditionalRequestParameters(OAuth2Client client) - { - client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.ClientCredentials); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta deleted file mode 100644 index 713fce7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b5705e0a64be19f4c9fa5fa73389c1a7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs deleted file mode 100644 index 776b5c3..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs +++ /dev/null @@ -1,274 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.Interfaces; -using Microsoft.Identity.Client.Internal.OAuth2; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class InteractiveRequest : RequestBase - { - private readonly SortedSet _extraScopesToConsent; - private readonly UIBehavior _UIBehavior; - private readonly IWebUI _webUi; - private AuthorizationResult _authorizationResult; - private string _codeVerifier; - private string _state; - - public InteractiveRequest(AuthenticationRequestParameters authenticationRequestParameters, - IEnumerable extraScopesToConsent, UIBehavior UIBehavior, IWebUI webUI) - : this( - authenticationRequestParameters, extraScopesToConsent, authenticationRequestParameters.User?.DisplayableId, - UIBehavior, webUI) - { - } - - public InteractiveRequest(AuthenticationRequestParameters authenticationRequestParameters, - IEnumerable extraScopesToConsent, string loginHint, - UIBehavior UIBehavior, IWebUI webUI) - : base(authenticationRequestParameters) - { - PlatformPlugin.PlatformInformation.ValidateRedirectUri(authenticationRequestParameters.RedirectUri, - authenticationRequestParameters.RequestContext); - if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.RedirectUri.Fragment)) - { - throw new ArgumentException(MsalErrorMessage.RedirectUriContainsFragment, nameof(authenticationRequestParameters.RedirectUri)); - } - - _extraScopesToConsent = new SortedSet(); - if (!MsalHelpers.IsNullOrEmpty(extraScopesToConsent)) - { - _extraScopesToConsent = extraScopesToConsent.CreateSetFromEnumerable(); - } - - ValidateScopeInput(_extraScopesToConsent); - - authenticationRequestParameters.LoginHint = loginHint; - if (!string.IsNullOrWhiteSpace(authenticationRequestParameters.ExtraQueryParameters) && - authenticationRequestParameters.ExtraQueryParameters[0] == '&') - { - authenticationRequestParameters.ExtraQueryParameters = - authenticationRequestParameters.ExtraQueryParameters.Substring(1); - } - - _webUi = webUI; - _UIBehavior = UIBehavior; - LoadFromCache = false; //no cache lookup and refresh for interactive. - var msg = "Additional scopes - " + _extraScopesToConsent.AsSingleString() + ";" + "UIBehavior - " + - _UIBehavior.PromptValue; - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - } - - protected override string GetUIBehaviorPromptValue() - { - return _UIBehavior.PromptValue; - } - - internal override async Task PreTokenRequestAsync() - { - await base.PreTokenRequestAsync().ConfigureAwait(false); - await AcquireAuthorizationAsync().ConfigureAwait(false); - VerifyAuthorizationResult(); - } - - internal async Task AcquireAuthorizationAsync() - { - Uri authorizationUri = CreateAuthorizationUri(true, true); - var uiEvent = new UiEvent(); - Client.Telemetry.GetInstance().StartEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, uiEvent); - try - { - _authorizationResult = await - _webUi.AcquireAuthorizationAsync(authorizationUri, AuthenticationRequestParameters.RedirectUri, - AuthenticationRequestParameters.RequestContext) - .ConfigureAwait(false); - uiEvent.UserCancelled = _authorizationResult.Status == AuthorizationStatus.UserCancel; - } - finally - { - Client.Telemetry.GetInstance().StopEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, uiEvent); - } - } - - internal async Task CreateAuthorizationUriAsync() - { - //this method is used in confidential clients to create authorization URLs. - await AuthenticationRequestParameters.Authority.ResolveEndpointsAsync(AuthenticationRequestParameters.LoginHint, AuthenticationRequestParameters.RequestContext).ConfigureAwait(false); - return CreateAuthorizationUri(); - } - - protected override void SetAdditionalRequestParameters(OAuth2Client client) - { - client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.AuthorizationCode); - client.AddBodyParameter(OAuth2Parameter.Code, _authorizationResult.Code); - client.AddBodyParameter(OAuth2Parameter.RedirectUri, AuthenticationRequestParameters.RedirectUri.OriginalString); - client.AddBodyParameter(OAuth2Parameter.CodeVerifier, _codeVerifier); - } - - private Uri CreateAuthorizationUri(bool addVerifier = false, bool addState = false) - { - IDictionary requestParameters = CreateAuthorizationRequestParameters(); - - if (addVerifier) - { - _codeVerifier = CryptographyHelper.GenerateCodeVerifier(); - string codeVerifierHash = CryptographyHelper.CreateBase64UrlEncodedSha256Hash(_codeVerifier); - - requestParameters[OAuth2Parameter.CodeChallenge] = codeVerifierHash; - requestParameters[OAuth2Parameter.CodeChallengeMethod] = OAuth2Value.CodeChallengeMethodValue; - } - - if (addState) - { - _state = Guid.NewGuid().ToString(); - requestParameters[OAuth2Parameter.State] = _state; - } - - //add uid/utid values to QP if user object was passed in. - if (AuthenticationRequestParameters.User != null) - { - if (!string.IsNullOrEmpty(AuthenticationRequestParameters.User.DisplayableId)) - { - requestParameters[OAuth2Parameter.LoginHint] = AuthenticationRequestParameters.User.DisplayableId; - } - - AuthenticationRequestParameters.ClientInfo = ClientInfo.CreateFromEncodedString(AuthenticationRequestParameters.User.Identifier); - - if (!string.IsNullOrEmpty(AuthenticationRequestParameters.ClientInfo.UniqueIdentifier)) - { - requestParameters[OAuth2Parameter.LoginReq] = AuthenticationRequestParameters.ClientInfo.UniqueIdentifier; - } - - if (!string.IsNullOrEmpty(AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier)) - { - requestParameters[OAuth2Parameter.DomainReq] = AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier; - } - } - - CheckForDuplicateQueryParameters(AuthenticationRequestParameters.ExtraQueryParameters, requestParameters); - CheckForDuplicateQueryParameters(AuthenticationRequestParameters.SliceParameters, requestParameters); - - string qp = requestParameters.ToQueryParameter(); - UriBuilder builder = - new UriBuilder(new Uri(AuthenticationRequestParameters.Authority.AuthorizationEndpoint)); - builder.AppendQueryParameters(qp); - - return builder.Uri; - } - - private void CheckForDuplicateQueryParameters(string queryParams, IDictionary requestParameters) - { - if (!string.IsNullOrWhiteSpace(queryParams)) - { - // Checks for _extraQueryParameters duplicating standard parameters - Dictionary kvps = - MsalHelpers.ParseKeyValueList(queryParams, '&', false, - AuthenticationRequestParameters.RequestContext); - - foreach (KeyValuePair kvp in kvps) - { - if (requestParameters.ContainsKey(kvp.Key)) - { - throw new MsalClientException(MsalClientException.DuplicateQueryParameterError, - string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.DuplicateQueryParameterTemplate, - kvp.Key)); - } - - requestParameters[kvp.Key] = kvp.Value; - } - } - } - - private Dictionary CreateAuthorizationRequestParameters() - { - SortedSet unionScope = - GetDecoratedScope( - new SortedSet(AuthenticationRequestParameters.Scope.Union(_extraScopesToConsent))); - - Dictionary authorizationRequestParameters = new Dictionary(); - authorizationRequestParameters[OAuth2Parameter.Scope] = unionScope.AsSingleString(); - authorizationRequestParameters[OAuth2Parameter.ResponseType] = OAuth2ResponseType.Code; - - authorizationRequestParameters[OAuth2Parameter.ClientId] = AuthenticationRequestParameters.ClientId; - authorizationRequestParameters[OAuth2Parameter.RedirectUri] = - AuthenticationRequestParameters.RedirectUri.OriginalString; - - if (!string.IsNullOrWhiteSpace(AuthenticationRequestParameters.LoginHint)) - { - authorizationRequestParameters[OAuth2Parameter.LoginHint] = AuthenticationRequestParameters.LoginHint; - } - - if (!string.IsNullOrEmpty(AuthenticationRequestParameters.RequestContext?.CorrelationId)) - { - authorizationRequestParameters[OAuth2Parameter.CorrelationId] = AuthenticationRequestParameters.RequestContext.CorrelationId; - } - - IDictionary adalIdParameters = MsalIdHelper.GetMsalIdParameters(); - foreach (KeyValuePair kvp in adalIdParameters) - { - authorizationRequestParameters[kvp.Key] = kvp.Value; - } - - authorizationRequestParameters[OAuth2Parameter.Prompt] = _UIBehavior.PromptValue; - return authorizationRequestParameters; - } - - private void VerifyAuthorizationResult() - { - if (_authorizationResult.Status == AuthorizationStatus.Success && !_state.Equals(_authorizationResult.State)) - { - throw new MsalClientException(MsalClientException.StateMismatchError, - string.Format(CultureInfo.InvariantCulture, "Returned state({0}) from authorize endpoint is not the same as the one sent({1})", _authorizationResult.State, _state)); - } - - if (_authorizationResult.Error == OAuth2Error.LoginRequired) - { - throw new MsalUiRequiredException(MsalUiRequiredException.NoPromptFailedError, - MsalErrorMessage.NoPromptFailedErrorMessage); - } - - if (_authorizationResult.Status == AuthorizationStatus.UserCancel) - { - throw new MsalClientException(_authorizationResult.Error, - _authorizationResult.ErrorDescription); - } - - if (_authorizationResult.Status != AuthorizationStatus.Success) - { - throw new MsalServiceException(_authorizationResult.Error, - _authorizationResult.ErrorDescription); - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta deleted file mode 100644 index 22aac0d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/InteractiveRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2629c1ec4acd3704c9b1bf4ba9f0bed2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs deleted file mode 100644 index 0df270b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs +++ /dev/null @@ -1,77 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class OnBehalfOfRequest : RequestBase - { - public OnBehalfOfRequest(AuthenticationRequestParameters authenticationRequestParameters) - : base(authenticationRequestParameters) - { - if (authenticationRequestParameters.UserAssertion == null) - { - throw new ArgumentNullException(nameof(authenticationRequestParameters.UserAssertion)); - } - } - - internal override async Task PreTokenRequestAsync() - { - await base.PreTokenRequestAsync().ConfigureAwait(false); - - // look for access token in the cache first. - // no access token is found, then it means token does not exist - // or new assertion has been passed. We should not use Refresh Token - // for the user because the new incoming token may have updated claims - // like mfa etc. - if (LoadFromCache) - { - AccessTokenItem - = TokenCache.FindAccessToken(AuthenticationRequestParameters); - } - } - - protected override async Task SendTokenRequestAsync() - { - if (AccessTokenItem == null) - { - await base.SendTokenRequestAsync().ConfigureAwait(false); - } - } - - protected override void SetAdditionalRequestParameters(OAuth2Client client) - { - client.AddBodyParameter(OAuth2Parameter.GrantType, - AuthenticationRequestParameters.UserAssertion.AssertionType); - client.AddBodyParameter(OAuth2Parameter.Assertion, AuthenticationRequestParameters.UserAssertion.Assertion); - client.AddBodyParameter(OAuth2Parameter.RequestedTokenUse, OAuth2RequestedTokenUse.OnBehalfOf); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta deleted file mode 100644 index 2a392fa..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/OnBehalfOfRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 81efa6aa48470c5409cfba16848e25dd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs deleted file mode 100644 index 52e9a58..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs +++ /dev/null @@ -1,315 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.Cache; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.OAuth2; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal abstract class RequestBase - { - protected static readonly Task CompletedTask = Task.FromResult(false); - internal readonly AuthenticationRequestParameters AuthenticationRequestParameters; - internal readonly TokenCache TokenCache; - protected TokenResponse Response; - protected AccessTokenCacheItem AccessTokenItem; - public ApiEvent.ApiIds ApiId { get; set; } - public bool IsConfidentialClient { get; set; } - protected virtual string GetUIBehaviorPromptValue() - { - return null; - } - - protected bool SupportADFS { get; set; } - - protected bool LoadFromCache { get; set; } - - protected bool ForceRefresh { get; set; } - - protected bool StoreToCache { get; set; } - - protected RequestBase(AuthenticationRequestParameters authenticationRequestParameters) - { - TokenCache = authenticationRequestParameters.TokenCache; - - // Log contains Pii - authenticationRequestParameters.RequestContext.Logger.InfoPii(string.Format(CultureInfo.InvariantCulture, - "=== Token Acquisition ({4}) started:\n\tAuthority: {0}\n\tScope: {1}\n\tClientId: {2}\n\tCache Provided: {3}", - authenticationRequestParameters?.Authority?.CanonicalAuthority, - authenticationRequestParameters.Scope.AsSingleString(), - authenticationRequestParameters.ClientId, - TokenCache != null, this.GetType().Name)); - - // Log does not contain Pii - var msg = string.Format(CultureInfo.InvariantCulture, - "=== Token Acquisition ({1}) started:\n\tCache Provided: {0}", TokenCache != null, this.GetType().Name); - - if (authenticationRequestParameters.Authority != null && - AadAuthority.IsInTrustedHostList(authenticationRequestParameters.Authority.Host)) - { - msg += string.Format(CultureInfo.CurrentCulture, "\n\tAuthority Host: {0}", - authenticationRequestParameters.Authority.Host); - } - authenticationRequestParameters.RequestContext.Logger.Info(msg); - - AuthenticationRequestParameters = authenticationRequestParameters; - if (authenticationRequestParameters.Scope == null || authenticationRequestParameters.Scope.Count == 0) - { - throw new ArgumentNullException(nameof(authenticationRequestParameters.Scope)); - } - - ValidateScopeInput(authenticationRequestParameters.Scope); - LoadFromCache = (TokenCache != null); - StoreToCache = (TokenCache != null); - SupportADFS = false; - - AuthenticationRequestParameters.LogState(); - Client.Telemetry.GetInstance().ClientId = AuthenticationRequestParameters.ClientId; - } - - protected virtual SortedSet GetDecoratedScope(SortedSet inputScope) - { - SortedSet set = new SortedSet(inputScope.ToArray()); - set.UnionWith(OAuth2Value.ReservedScopes.CreateSetFromEnumerable()); - return set; - } - - protected void ValidateScopeInput(SortedSet scopesToValidate) - { - //check if scope or additional scope contains client ID. - if (scopesToValidate.Intersect(OAuth2Value.ReservedScopes.CreateSetFromEnumerable()).Any()) - { - throw new ArgumentException("MSAL always sends the scopes 'openid profile offline_access'. " + - "They cannot be suppressed as they are required for the " + - "library to function. Do not include any of these scopes in the scope parameter."); - } - - if (scopesToValidate.Contains(AuthenticationRequestParameters.ClientId)) - { - throw new ArgumentException("API does not accept client id as a user-provided scope"); - } - } - - public async Task RunAsync() - { - //this method is the common entrance for all token requests, so it is a good place to put the generic Telemetry logic here - AuthenticationRequestParameters.RequestContext.TelemetryRequestId = Client.Telemetry.GetInstance().GenerateNewRequestId(); - var apiEvent = new ApiEvent() - { - ApiId = ApiId, - ValidationStatus = AuthenticationRequestParameters.ValidateAuthority.ToString(), - UserId = AuthenticationRequestParameters.User != null ? AuthenticationRequestParameters.User.Identifier : "", - CorrelationId = AuthenticationRequestParameters.RequestContext.CorrelationId, - RequestId = AuthenticationRequestParameters.RequestContext.TelemetryRequestId, - IsConfidentialClient = IsConfidentialClient, - UiBehavior = GetUIBehaviorPromptValue(), - WasSuccessful = false - }; - - if (AuthenticationRequestParameters.Authority != null) - { - apiEvent.Authority = new Uri(AuthenticationRequestParameters.Authority.CanonicalAuthority); - apiEvent.AuthorityType = AuthenticationRequestParameters.Authority.AuthorityType.ToString(); - } - - Client.Telemetry.GetInstance().StartEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, apiEvent); - - try - { - //authority endpoints resolution and validation - await PreTokenRequestAsync().ConfigureAwait(false); - await SendTokenRequestAsync().ConfigureAwait(false); - AuthenticationResult result = PostTokenRequest(); - await PostRunAsync(result).ConfigureAwait(false); - - apiEvent.TenantId = result.TenantId; - apiEvent.UserId = result.UniqueId; - apiEvent.WasSuccessful = true; - return result; - } - catch (MsalException ex) - { - apiEvent.ApiErrorCode = ex.ErrorCode; - AuthenticationRequestParameters.RequestContext.Logger.Error(ex); - AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(ex); - throw; - } - catch (Exception ex) - { - AuthenticationRequestParameters.RequestContext.Logger.Error(ex); - AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(ex); - throw; - } - finally - { - Client.Telemetry.GetInstance().StopEvent(AuthenticationRequestParameters.RequestContext.TelemetryRequestId, apiEvent); - Client.Telemetry.GetInstance().Flush(AuthenticationRequestParameters.RequestContext.TelemetryRequestId); - } - } - - private AccessTokenCacheItem SaveTokenResponseToCache() - { - // developer passed in user object. - string msg = "checking client info returned from the server.."; - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - - ClientInfo fromServer = null; - - if (!AuthenticationRequestParameters.IsClientCredentialRequest) - { - //client_info is not returned from client credential flows because there is no user present. - fromServer = ClientInfo.CreateFromJson(Response.ClientInfo); - } - - if (fromServer!= null && AuthenticationRequestParameters.ClientInfo != null) - { - if (!fromServer.UniqueIdentifier.Equals(AuthenticationRequestParameters.ClientInfo.UniqueIdentifier) || - !fromServer.UniqueTenantIdentifier.Equals(AuthenticationRequestParameters.ClientInfo - .UniqueTenantIdentifier)) - { - AuthenticationRequestParameters.RequestContext.Logger.ErrorPii(String.Format( - CultureInfo.InvariantCulture, - "Returned user identifiers (uid:{0} utid:{1}) does not meatch the sent user identifier (uid:{2} utid:{3})", - fromServer.UniqueIdentifier, fromServer.UniqueTenantIdentifier, - AuthenticationRequestParameters.ClientInfo.UniqueIdentifier, - AuthenticationRequestParameters.ClientInfo.UniqueTenantIdentifier)); - - AuthenticationRequestParameters.RequestContext.Logger.Error("Returned user identifiers do not match the sent user" + - "identifier"); - - throw new MsalServiceException("user_mismatch", "Returned user identifier does not match the sent user identifier"); - } - } - - IdToken idToken = IdToken.Parse(Response.IdToken); - AuthenticationRequestParameters.TenantUpdatedCanonicalAuthority = Authority.UpdateTenantId( - AuthenticationRequestParameters.Authority.CanonicalAuthority, idToken?.TenantId); - - if (StoreToCache) - { - msg = "Saving Token Response to cache.."; - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - - return TokenCache.SaveAccessAndRefreshToken(AuthenticationRequestParameters, Response); - } - - return new AccessTokenCacheItem(AuthenticationRequestParameters.TenantUpdatedCanonicalAuthority, - AuthenticationRequestParameters.ClientId, Response); - } - - protected virtual Task PostRunAsync(AuthenticationResult result) - { - LogReturnedToken(result); - return CompletedTask; - } - - internal virtual async Task PreTokenRequestAsync() - { - await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); - } - - - internal async Task ResolveAuthorityEndpointsAsync() - { - await AuthenticationRequestParameters.Authority - .ResolveEndpointsAsync(AuthenticationRequestParameters.LoginHint, - AuthenticationRequestParameters.RequestContext) - .ConfigureAwait(false); - } - - - protected virtual AuthenticationResult PostTokenRequest() - { - //save to cache if no access token item found - //this means that no cached item was found - if (AccessTokenItem == null) - { - AccessTokenItem = SaveTokenResponseToCache(); - } - - return new AuthenticationResult(AccessTokenItem); - } - - protected abstract void SetAdditionalRequestParameters(OAuth2Client client); - - protected virtual async Task SendTokenRequestAsync() - { - OAuth2Client client = new OAuth2Client(); - client.AddBodyParameter(OAuth2Parameter.ClientId, AuthenticationRequestParameters.ClientId); - client.AddBodyParameter(OAuth2Parameter.ClientInfo, "1"); - foreach (var entry in AuthenticationRequestParameters.ToParameters()) - { - client.AddBodyParameter(entry.Key, entry.Value); - } - - client.AddBodyParameter(OAuth2Parameter.Scope, - GetDecoratedScope(AuthenticationRequestParameters.Scope).AsSingleString()); - SetAdditionalRequestParameters(client); - await SendHttpMessageAsync(client).ConfigureAwait(false); - } - - private async Task SendHttpMessageAsync(OAuth2Client client) - { - UriBuilder builder = new UriBuilder(AuthenticationRequestParameters.Authority.TokenEndpoint); - builder.AppendQueryParameters(AuthenticationRequestParameters.SliceParameters); - Response = - await client - .GetTokenAsync(builder.Uri, - AuthenticationRequestParameters.RequestContext) - .ConfigureAwait(false); - - if (string.IsNullOrEmpty(Response.Scope)) - { - Response.Scope = AuthenticationRequestParameters.Scope.AsSingleString(); - const string msg = "ScopeSet was missing from the token response, so using developer provided scopes in the result"; - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - - } - } - - private void LogReturnedToken(AuthenticationResult result) - { - if (result.AccessToken != null) - { - var msg = string.Format(CultureInfo.InvariantCulture, "=== Token Acquisition finished successfully. An access token was returned with Expiration Time: {0} ===", - result.ExpiresOn); - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta deleted file mode 100644 index 760640b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8bb114f9b17f2e34f8f55bd2fb3409fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs deleted file mode 100644 index cb5eb0e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs +++ /dev/null @@ -1,108 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.OAuth2; -using Microsoft.Identity.Client.Internal.Cache; - -namespace Microsoft.Identity.Client.Internal.Requests -{ - internal class SilentRequest : RequestBase - { - private RefreshTokenCacheItem _refreshTokenItem; - - public SilentRequest(AuthenticationRequestParameters authenticationRequestParameters, bool forceRefresh) - : base(authenticationRequestParameters) - { - if (authenticationRequestParameters.User == null) - { - throw new MsalUiRequiredException(MsalUiRequiredException.UserNullError, "Null user was passed in AcquiretokenSilent API. Pass in " + - "a user object or call acquireToken authenticate."); - } - - ForceRefresh = forceRefresh; - } - - protected override void SetAdditionalRequestParameters(OAuth2Client client) - { - client.AddBodyParameter(OAuth2Parameter.GrantType, OAuth2GrantType.RefreshToken); - client.AddBodyParameter(OAuth2Parameter.RefreshToken, _refreshTokenItem.RefreshToken); - } - - internal override async Task PreTokenRequestAsync() - { - if (!LoadFromCache) - { - throw new MsalUiRequiredException(MsalUiRequiredException.TokenCacheNullError, - "Token cache is set to null. Silent requests cannot be executed."); - } - - //look for access token. - AccessTokenItem - = TokenCache.FindAccessToken(AuthenticationRequestParameters); - - if (ForceRefresh) - { - AccessTokenItem = null; - } - - await CompletedTask.ConfigureAwait(false); - } - - protected override async Task SendTokenRequestAsync() - { - if (AccessTokenItem == null) - { - _refreshTokenItem = - TokenCache.FindRefreshToken(AuthenticationRequestParameters); - - if (_refreshTokenItem == null) - { - const string msg = "No Refresh Token was found in the cache"; - AuthenticationRequestParameters.RequestContext.Logger.Verbose(msg); - AuthenticationRequestParameters.RequestContext.Logger.VerbosePii(msg); - - throw new MsalUiRequiredException(MsalUiRequiredException.NoTokensFoundError, - "No Refresh Token found in the cache"); - } - - AuthenticationRequestParameters.RequestContext.Logger.Verbose("Refreshing access token..."); - await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); - await base.SendTokenRequestAsync().ConfigureAwait(false); - - if (Response.RefreshToken == null) - { - Response.RefreshToken = _refreshTokenItem.RefreshToken; - const string msg = "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead"; - AuthenticationRequestParameters.RequestContext.Logger.Info(msg); - AuthenticationRequestParameters.RequestContext.Logger.InfoPii(msg); - } - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta deleted file mode 100644 index a44b4f4..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Requests/SilentRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3cc06d1c95ecb0c429b51f64e52422c2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta deleted file mode 100644 index 40f4416..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7e9f8434bad8cf64b8688555924713ea -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs deleted file mode 100644 index 6fe3c1f..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs +++ /dev/null @@ -1,173 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - - -using System; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class ApiEvent : EventBase - { - public const string ApiIdKey = EventNamePrefix + "api_id"; - public const string AuthorityKey = EventNamePrefix + "authority"; - public const string AuthorityTypeKey = EventNamePrefix + "authority_type"; - public const string UiBehaviorKey = EventNamePrefix + "ui_behavior"; - public const string ValidationStatusKey = EventNamePrefix + "validation_status"; - public const string TenantIdKey = EventNamePrefix + "tenant_id"; - public const string UserIdKey = EventNamePrefix + "user_id"; - public const string WasSuccessfulKey = EventNamePrefix + "was_successful"; - public const string CorrelationIdKey = EventNamePrefix + "correlation_id"; - public const string RequestIdKey = EventNamePrefix + "request_id"; - public const string IsConfidentialClientKey = EventNamePrefix + "is_confidential_client"; - public const string ApiErrorCodeKey = EventNamePrefix + "api_error_code"; - - public enum ApiIds - { - AcquireTokenSilentWithAuthority = 31, - AcquireTokenSilentWithoutAuthority = 30, - - AcquireTokenWithScope = 170, - AcquireTokenWithScopeHint = 171, - AcquireTokenWithScopeHintBehavior = 172, - AcquireTokenWithScopeHintBehaviorAuthority = 173, - AcquireTokenWithScopeUser = 176, - AcquireTokenWithScopeUserBehavior = 174, - AcquireTokenWithScopeUserBehaviorAuthority = 175, - - AcquireTokenOnBehalfOfWithScopeUser = 520, - AcquireTokenOnBehalfOfWithScopeUserAuthority = 521, - - AcquireTokenForClientWithScope = 726, - AcquireTokenForClientWithScopeRefresh = 727, - - AcquireTokenByAuthorizationCodeWithCodeScope = 830, - } - - public ApiEvent() : base(EventNamePrefix + "api_event") { } - - public ApiIds ApiId - { - set - { - this[ApiIdKey] = ((int)value).ToStringInvariant(); - } - } - - public Uri Authority - { - set - { - this[AuthorityKey] = ScrubTenant(value)?.ToLowerInvariant(); - } - } - - public string AuthorityType - { - set - { - this[AuthorityTypeKey] = value?.ToLowerInvariant(); - } - } - - public string UiBehavior - { - set - { - this[UiBehaviorKey] = value?.ToLowerInvariant(); - } - } - - public string ValidationStatus - { - set - { - this[ValidationStatusKey] = value?.ToLowerInvariant(); - } - } - - public string TenantId - { - set - { - this[TenantIdKey] = value != null && Logger.PiiLoggingEnabled ? CryptographyHelper.CreateBase64UrlEncodedSha256Hash(value) : null; - } - } - - public string UserId - { - set - { - this[UserIdKey] = value != null && Logger.PiiLoggingEnabled ? CryptographyHelper.CreateBase64UrlEncodedSha256Hash(value) : null; - } - } - - public bool WasSuccessful - { - set - { - this[WasSuccessfulKey] = value.ToString().ToLowerInvariant(); - } - - get - { - return this[WasSuccessfulKey] == true.ToString().ToLowerInvariant(); - } - } - - public string CorrelationId - { - set - { - this[CorrelationIdKey] = value; - } - } - - public string RequestId - { - set - { - this[RequestIdKey] = value; - } - } - - public bool IsConfidentialClient - { - set - { - this[IsConfidentialClientKey] = value.ToString().ToLowerInvariant(); - } - } - - public string ApiErrorCode - { - set - { - this[ApiErrorCodeKey] = value; - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta deleted file mode 100644 index f6c68f0..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/ApiEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a1d296f68afaa5847a38f26a9b003b35 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs deleted file mode 100644 index 135fb15..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs +++ /dev/null @@ -1,67 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - - -using System.Collections.Generic; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class CacheEvent : EventBase - { - public const string TokenCacheLookup = EventNamePrefix + "token_cache_lookup"; - public const string TokenCacheWrite = EventNamePrefix + "token_cache_write"; - public const string TokenCacheBeforeAccess = EventNamePrefix + "token_cache_before_access"; - public const string TokenCacheAfterAccess = EventNamePrefix + "token_cache_after_access"; - public const string TokenCacheBeforeWrite = EventNamePrefix + "token_cache_before_write"; - public const string TokenCacheDelete = EventNamePrefix + "token_cache_delete"; - - public const string TokenTypeKey = EventNamePrefix + "token_type"; - - public CacheEvent(string eventName) : base(eventName) - { - } - - public enum TokenTypes - { - AT, - RT - }; - - public TokenTypes TokenType - { - set - { - var types = new Dictionary() - { - {TokenTypes.AT, "at"}, - {TokenTypes.RT, "rt"} - }; - this[TokenTypeKey] = types[value]; - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta deleted file mode 100644 index 773515b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/CacheEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f22d2f1a5561cbf438ee7d9bf4c4d8c9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs deleted file mode 100644 index dea3276..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs +++ /dev/null @@ -1,45 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class DefaultEvent : EventBase - { - public DefaultEvent(string clientId) : base((string) (EventBase.EventNamePrefix + "default_event")) - { - this[EventNamePrefix + "client_id"] = clientId; - this[EventNamePrefix + "sdk_platform"] = PlatformPlugin.PlatformInformation.GetProductName()?.ToLowerInvariant(); - this[EventNamePrefix + "sdk_version"] = MsalIdHelper.GetMsalVersion(); - // TODO: The following implementation will be used after the 3 helpers being implemented (in a separated PR) - // this[EventNamePrefix + "application_name"] = MsalIdHelper.GetApplicationName(); // Not yet implemented - // this[EventNamePrefix + "application_version"] = MsalIdHelper.GetApplicationVersion(); // Not yet implemented - // this[EventNamePrefix + "device_id"] = MsalIdHelper.GetDeviceId(); // Not yet implemented - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta deleted file mode 100644 index 2b378bb..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/DefaultEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 73826c4a534e8b1469fe3ace0d05082e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs deleted file mode 100644 index 03e0c84..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs +++ /dev/null @@ -1,90 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Instance; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal abstract class EventBase : Dictionary - { - protected const string EventNamePrefix = "msal."; - public const string EventNameKey = EventNamePrefix + "event_name"; - public const string StartTimeKey = EventNamePrefix + "start_time"; - public const string ElapsedTimeKey = EventNamePrefix + "elapsed_time"; - private readonly long _startTimestamp; - - public const string TenantPlaceHolder = ""; // It is used to replace the real tenant in telemetry info - - public EventBase(string eventName) : this(eventName, new Dictionary()) {} - - protected static long CurrentUnixTimeMilliseconds() - { - return MsalHelpers.DateTimeToUnixTimestampMilliseconds(DateTimeOffset.Now); - } - - public EventBase(string eventName, IDictionary predefined) : base(predefined) - { - this[EventNameKey] = eventName; - _startTimestamp = CurrentUnixTimeMilliseconds(); - this[StartTimeKey] = _startTimestamp.ToStringInvariant(); - this[ElapsedTimeKey] = "-1"; - } - - public void Stop() - { - this[ElapsedTimeKey] = (CurrentUnixTimeMilliseconds() - _startTimestamp).ToStringInvariant(); // It is a duration - } - - public static string ScrubTenant(Uri uri) // Note: There is also a Unit Test case for this helper - { - if (!uri.IsAbsoluteUri) - { - throw new ArgumentException("Requires an absolute uri"); - } - if (!AadAuthority.IsInTrustedHostList(uri.Host)) // only collect telemetry for well-known hosts - { - return null; - } - - var pieces = uri.AbsolutePath.Split('/'); // It looks like {"", "common", "oauth2", "v2.0", "token"} - if (pieces.Length >= 2) - { - int tenantPosition = pieces[1] == B2CAuthority.Prefix ? 2 : 1; - if (tenantPosition < pieces.Length) - { - // Replace it rather than remove it. Otherwise the end result would misleadingly look like a complete URL while it is actually not. - pieces[tenantPosition] = TenantPlaceHolder; - } - } - string scrubbedPath = String.Join("/", pieces); - return uri.Scheme + "://" + uri.Authority + scrubbedPath; - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta deleted file mode 100644 index 46cbe8f..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/Event.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 146a9cf6465409543ae8c26dcdbda5d1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs deleted file mode 100644 index 83c0184..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs +++ /dev/null @@ -1,93 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - - -using System; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class HttpEvent : EventBase - { - public const string HttpPathKey = EventNamePrefix + "http_path"; - public const string UserAgentKey = EventNamePrefix + "user_agent"; - public const string QueryParametersKey = EventNamePrefix + "query_parameters"; - public const string ApiVersionKey = EventNamePrefix + "api_version"; - public const string ResponseCodeKey = EventNamePrefix + "response_code"; - public const string OauthErrorCodeKey = EventNamePrefix + "oauth_error_code"; - - public HttpEvent() : base(EventNamePrefix + "http_event") { } - - public Uri HttpPath - { - set - { - this[HttpPathKey] = ScrubTenant(value); - } - } - - public string UserAgent - { - set - { - this[UserAgentKey] = value; - } - } - - public string QueryParams - { - set - { - this[QueryParametersKey] = String.Join( // query parameters are case-sensitive - "&", MsalHelpers.ParseKeyValueList(value, '&', false, true, null).Keys); // It turns out ParseKeyValueList(..., null) is valid - } - } - - public string ApiVersion - { - set - { - this[ApiVersionKey] = value?.ToLowerInvariant(); - } - } - - public int HttpResponseStatus - { - set - { - this[ResponseCodeKey] = value.ToStringInvariant(); - } - } - - public string OauthErrorCode - { - set - { - this[OauthErrorCodeKey] = value; - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta deleted file mode 100644 index a487bea..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/HttpEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 13fc505878f8794418d86bd659c49774 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs deleted file mode 100644 index b50685c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs +++ /dev/null @@ -1,92 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using Microsoft.Identity.Client; - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class TelemetryTokenCacheAccessor : TokenCacheAccessor - { - // The content of this class has to be placed outside of its base class TokenCacheAccessor, - // otherwise we would have to modify multiple implementations of TokenCacheAccessor on different platforms. - public void SaveAccessToken(string cacheKey, string item, RequestContext requestContext) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheWrite) { TokenType = CacheEvent.TokenTypes.AT }; - Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); - try - { - SaveAccessToken(cacheKey, item); - } - finally - { - Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); - } - } - - public void SaveRefreshToken(string cacheKey, string item, RequestContext requestContext) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheWrite) { TokenType = CacheEvent.TokenTypes.RT }; - Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); - try - { - SaveRefreshToken(cacheKey, item); - } - finally - { - Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); - } - } - - public void DeleteAccessToken(string cacheKey, RequestContext requestContext) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheDelete) { TokenType = CacheEvent.TokenTypes.AT }; - Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); - try - { - DeleteAccessToken(cacheKey); - } - finally - { - Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); - } - } - - public void DeleteRefreshToken(string cacheKey, RequestContext requestContext) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheDelete) { TokenType = CacheEvent.TokenTypes.RT }; - Client.Telemetry.GetInstance().StartEvent(requestContext.TelemetryRequestId, cacheEvent); - try - { - DeleteRefreshToken(cacheKey); - } - finally - { - Client.Telemetry.GetInstance().StopEvent(requestContext.TelemetryRequestId, cacheEvent); - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta deleted file mode 100644 index fae90c7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/TelemetryTokenCacheAccessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e84a3a1ded71c1f45bdf664632acbb64 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs deleted file mode 100644 index 4aa34f2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs +++ /dev/null @@ -1,45 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - - -namespace Microsoft.Identity.Client.Internal.Telemetry -{ - internal class UiEvent : EventBase - { - public const string UserCancelledKey = EventNamePrefix + "user_cancelled"; - - public UiEvent() : base(EventNamePrefix + "ui_event") { } - - public bool UserCancelled - { - set - { - this[UserCancelledKey] = value.ToString().ToLowerInvariant(); - } - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta deleted file mode 100644 index 834e5c1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Internal/Telemetry/UiEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 26180f0febbf25e4eb3a1c9c369c6b72 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs deleted file mode 100644 index 011ebc4..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs +++ /dev/null @@ -1,267 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; -using Microsoft.Identity.Client.Internal; -using Exception = System.Exception; - -namespace Microsoft.Identity.Client -{ - /// - /// Callback delegate that allows the developer to consume logs handle them in a custom manner. - /// - /// Log level of the message - /// Pre-formatted log message - /// Indicates if the log message contains PII. If Logger.PiiLoggingEnabled is set to - /// false then this value is always false. - public delegate void LogCallback(Logger.LogLevel level, string message, bool containsPii); - - /// - /// MSAL Logger class that allows developers to configure log level, configure callbacks etc. - /// - public sealed class Logger - { - /// - /// MSAL Log Levels - /// - public enum LogLevel - { - /// - /// Error Log level - /// - Error = 0, - - /// - /// Warning Log level - /// - Warning = 1, - - /// - /// Information Log level - /// - Info = 2, - - /// - /// Verbose Log level - /// - Verbose = 3 - } - - internal Logger(Guid correlationId, string component) - { - CorrelationId = correlationId; - - Component = string.Empty; - if (!string.IsNullOrEmpty(component)) - { - //space is intentional for formatting of the message - Component = string.Format(CultureInfo.InvariantCulture, " ({0})", component); - } - } - - internal string Component { get; set; } - - private Guid CorrelationId { get; set; } - - private static readonly object LockObj = new object(); - - private static volatile LogCallback _logCallback; - /// - /// Callback instance that can be provided by the developer to consume and publish logs in a custom manner. - /// The property can only be set once and it will throw an ArgumentException if called twice. - /// - public static LogCallback LogCallback - { - set - { - lock (LockObj) - { - if (_logCallback != null) - { - throw new ArgumentException("MSAL logging callback can only be set once per process and" + - " should never change once set."); - } - - _logCallback = value; - } - } - } - - /// - /// Configurable log level. Default value is Info. - /// - public static LogLevel Level { get; set; } = LogLevel.Info; - - /// - /// Flag to enable/disable logging of PII data. PII logs are never written to default outputs like Console, Logcat or NSLog. - /// Default is set to false. - /// - public static bool PiiLoggingEnabled { get; set; } = false; - - /// - /// Flag to enable/disable logging to platform defaults. In Desktop/UWP, Event Tracing is used. In iOS, NSLog is used. - /// In android, logcat is used. - /// - internal static bool DefaultLoggingEnabled { get; set; } = false; - - internal static void ExecuteCallback(LogLevel level, string message, bool containsPii) - { - lock (LockObj) - { - _logCallback?.Invoke(level, message, containsPii); - } - } - - #region LogMessages - /// - /// Method for error logging - /// - internal void Error(string message) - { - LogMessage(message, LogLevel.Error, false); - } - - /// - /// Method for error logging of Pii - /// - internal void ErrorPii(string message) - { - LogMessage(message, LogLevel.Error, true); - } - - /// - /// Method for warning logging - /// - internal void Warning(string message) - { - LogMessage(message, LogLevel.Warning, false); - } - - /// - /// Method for warning logging of Pii - /// - internal void WarningPii(string message) - { - LogMessage(message, LogLevel.Warning, true); - } - - /// - /// Method for information logging - /// - internal void Info(string message) - { - LogMessage(message, LogLevel.Info, false); - } - - /// - /// Method for information logging for Pii - /// - internal void InfoPii(string message) - { - LogMessage(message, LogLevel.Info, true); - } - - /// - /// Method for verbose logging - /// - internal void Verbose(string message) - { - LogMessage(message, LogLevel.Verbose, false); - } - - /// - /// Method for verbose logging for Pii - /// - internal void VerbosePii(string message) - { - LogMessage(message, LogLevel.Verbose, true); - } - - /// - /// Method for error exception logging - /// Removes Pii from exception - /// - internal void Error(Exception ex) - { - Error(ex.GetPiiScrubbedDetails()); - } - - /// - /// Method for error exception logging for Pii - /// Contains Pii passed from exception - /// - internal void ErrorPii(Exception ex) - { - ErrorPii(ex.ToString()); - } - - #endregion - - private void LogMessage(string logMessage, LogLevel logLevel, bool containsPii) - { - if ((logLevel > Level) || (!PiiLoggingEnabled && containsPii)) - { - return; - } - - //format log message; - string correlationId = (CorrelationId.Equals(Guid.Empty)) - ? string.Empty - : " - " + CorrelationId; - - string os = "N/A"; - if (MsalIdHelper.GetMsalIdParameters().ContainsKey(MsalIdParameter.OS)) - { - os = MsalIdHelper.GetMsalIdParameters()[MsalIdParameter.OS]; - } - - string log = string.Format(CultureInfo.InvariantCulture, "MSAL {0} {1} {2} [{3}{4}]{5} {6}", - MsalIdHelper.GetMsalVersion(), - MsalIdHelper.GetMsalIdParameters()[MsalIdParameter.Product], - os, DateTime.UtcNow, correlationId, Component, logMessage); - - if (PiiLoggingEnabled && containsPii) - { - const string piiLogMsg = "(True) "; - log = piiLogMsg + log; - } - else - { - const string noPiiLogMsg = "(False) "; - log = noPiiLogMsg + log; - } - - if (DefaultLoggingEnabled) - { - PlatformPlugin.LogMessage(logLevel, log); - } - - ExecuteCallback(logLevel, log, containsPii); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta deleted file mode 100644 index bed90e7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Logger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f67aee32795848d43b68b281cf6a95aa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs deleted file mode 100644 index 9a6bfc3..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs +++ /dev/null @@ -1,151 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Globalization; -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client -{ - /// - /// This exception class represents errors that are local to the library or the device. - /// - public class MsalClientException : MsalException - { - /// - /// MultipleTokensMatched were matched. - /// - public const string MultipleTokensMatchedError = "multiple_matching_tokens_detected"; - - /// - /// Non HTTPS redirects are not supported. - /// - public const string NonHttpsRedirectNotSupported = "non_https_redirect_failed"; - - /// - /// The request could not be preformed because the network is down. - /// - public const string NetworkNotAvailableError = "network_not_available"; - - /// - /// Duplicate query parameter in extraQueryParameters - /// - public const string DuplicateQueryParameterError = "duplicate_query_parameter"; - - - /// - /// The request could not be preformed because of a failure in the UI flow. - /// - public const string AuthenticationUiFailedError = "authentication_ui_failed"; - - /// - /// Authentication canceled. - /// - public const string AuthenticationCanceledError = "authentication_canceled"; - - /// - /// JSON parsing failed. - /// - public const string JsonParseError = "json_parse_failed"; - - /// - /// JWT was invalid - /// - public const string InvalidJwtError = "invalid_jwt"; - - /// - /// State returned from the STS was different than the one sent. - /// - public const string StateMismatchError = "state_mismatch"; - - /// - /// Tenant discovery failed. - /// - public const string TenantDiscoveryFailedError = "tenant_discovery_failed"; - -#if ANDROID - - /// - /// Indicates that chrome is not installed on the device. The sdk uses chrome custom tab for - /// authorize request if applicable or fall back to chrome browser. - /// - public const string ChromeNotInstalledError = "chrome_not_installed"; - - /// - /// Indicates that chrome is installed on the device but disabled. The sdk uses chrome custom tab for - /// authorize request if applicable or fall back to chrome browser. - /// - public const string ChromeDisabledError = "chrome_disabled"; - - /// - /// The intent to launch AuthenticationActivity is not resolvable by the OS or the intent. - /// - public const string UnresolvableIntentError = "unresolvable_intent"; - -#endif - - - /// - /// Initializes a new instance of the exception class with a specified - /// error code. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - public MsalClientException(string errorCode) : base(errorCode) - { - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code and error message. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - public MsalClientException(string errorCode, string errorMessage):base(errorCode, errorMessage) - { - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and inner exception. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - /// - public MsalClientException(string errorCode, string errorMessage, Exception innerException):base(errorCode, errorMessage, innerException) - { - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta deleted file mode 100644 index 8d76f9c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalClientException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 017698f87adacf0448469eb563550907 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs deleted file mode 100644 index 2c13181..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs +++ /dev/null @@ -1,117 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client -{ - /// - /// The exception type thrown when an error occurs during token acquisition. - /// - public class MsalException : Exception - { - - /// - /// Unknown Error occured. - /// - public const string UnknownError = "unknown_error"; - - /// - /// Initializes a new instance of the exception class. - /// - public MsalException() - : base(MsalErrorMessage.Unknown) - { - ErrorCode = UnknownError; - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - public MsalException(string errorCode) - { - ErrorCode = errorCode; - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code and error message. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - public MsalException(string errorCode, string errorMessage) - : base(errorMessage) - { - ErrorCode = errorCode; - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - /// - /// The exception that is the cause of the current exception, or a null reference if no inner - /// exception is specified. - /// - public MsalException(string errorCode, string errorMessage, Exception innerException) - : base(errorMessage, innerException) - { - ErrorCode = errorCode; - } - - /// - /// Gets the protocol error code returned by the service or generated by client. This is the code you can rely on for - /// exception handling. - /// - public string ErrorCode { get; } - - /// - /// Creates and returns a string representation of the current exception. - /// - /// A string representation of the current exception. - public override string ToString() - { - return base.ToString() + string.Format(CultureInfo.InvariantCulture, "\n\tErrorCode: {0}", ErrorCode); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta deleted file mode 100644 index 2043e41..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8f7d89c5853f1cb4a84dcbe6d1f1da83 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs deleted file mode 100644 index f9e4ee2..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs +++ /dev/null @@ -1,178 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Globalization; - -namespace Microsoft.Identity.Client -{ - /// - /// The exception type thrown when service returns and error response or other networking errors occur. - /// - public class MsalServiceException : MsalException - { - /// - /// Service is unavailable and returned HTTP error code within the range of 500-599. - /// - public const string ServiceNotAvailable = "service_not_available"; - - /// - /// Http Request timed out. - /// - public const string RequestTimeout = "request_timeout"; - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The protocol error code returned by the service or generated by client. This is the code you - /// can rely on for exception handling. - /// - /// The error message that explains the reason for the exception. - public MsalServiceException(string errorCode, string errorMessage) - : base( - errorCode, errorMessage) - { - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The protocol error code returned by the service or generated by client. This is the code you - /// can rely on for exception handling. - /// - /// The error message that explains the reason for the exception. - /// Status code of the resposne received from the service. - public MsalServiceException(string errorCode, string errorMessage, int statusCode) - : this(errorCode, errorMessage) - { - StatusCode = statusCode; - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The protocol error code returned by the service or generated by client. This is the code you - /// can rely on for exception handling. - /// - /// The error message that explains the reason for the exception. - /// - /// The exception that is the cause of the current exception, or a null reference if no inner - /// exception is specified. - /// - public MsalServiceException(string errorCode, string errorMessage, - Exception innerException) - : base( - errorCode, errorMessage, innerException) - { - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The protocol error code returned by the service or generated by client. This is the code you - /// can rely on for exception handling. - /// - /// The error message that explains the reason for the exception. - /// Status code of the resposne received from the service. - /// - /// The exception that is the cause of the current exception, or a null reference if no inner - /// exception is specified. - /// - public MsalServiceException(string errorCode, string errorMessage, int statusCode, - Exception innerException) - : base( - errorCode, errorMessage, innerException) - { - StatusCode = statusCode; - } - - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and a reference to the inner exception that is the cause of - /// this exception. - /// - /// - /// The protocol error code returned by the service or generated by client. This is the code you - /// can rely on for exception handling. - /// - /// The error message that explains the reason for the exception. - /// The status code of the request. - /// The claims challenge returned back from the service. - /// - /// The exception that is the cause of the current exception, or a null reference if no inner - /// exception is specified. - /// - public MsalServiceException(string errorCode, string errorMessage, int statusCode, string claims, - Exception innerException) - : this( - errorCode, errorMessage, statusCode, innerException) - { - Claims = claims; - } - - /// - /// Gets the status code returned from http layer. This status code is either the HttpStatusCode in the inner - /// HttpRequestException response or - /// NavigateError Event Status Code in browser based flow (See - /// http://msdn.microsoft.com/en-us/library/bb268233(v=vs.85).aspx). - /// You can use this code for purposes such as implementing retry logic or error investigation. - /// - public int StatusCode { get; } = 0; - - /// - /// - /// - public string Claims { get; internal set; } - - /// - /// Raw response body received from the server. - /// - public string ResponseBody { get; internal set; } - - /// - /// Creates and returns a string representation of the current exception. - /// - /// A string representation of the current exception. - public override string ToString() - { - return base.ToString() + string.Format(CultureInfo.InvariantCulture, "\n\tStatusCode: {0}\n\tClaims: {1}", StatusCode, Claims); - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta deleted file mode 100644 index d2c680b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalServiceException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8cd474afd27c334a8896fdb5a8d9885 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs deleted file mode 100644 index cc908c0..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs +++ /dev/null @@ -1,97 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client -{ - /// - /// This exception class is to inform developers that UI interaction is required for authentication to - /// succeed. - /// - public class MsalUiRequiredException : MsalServiceException - { - /// - /// Standard OAuth2 protocol error code. It indicates to the libray that the user needs to go the UI for - /// getting a new token. - /// - public static readonly string InvalidGrantError = "invalid_grant"; - - /// - /// No tokens were found matching the criteria. - /// - public static readonly string NoTokensFoundError = "no_tokens_found"; - - /// - /// This error code comes back from AcquireTokenSilent calls when null user is - /// passed into AcquireTokenSilent calls. - /// - public static readonly string UserNullError = "user_null"; - - /// - /// This error code comes back from AcquireTokenSilent calls when null token cache reference - /// is passed into the application constructor - /// - public static readonly string TokenCacheNullError = "token_cache_null"; - - /// - /// One of two conditions was encountered. - /// 1. The PromptBehavior.Never flag was passed and but the constraint could not be honored - /// because user interaction was required. - /// 2. An error occurred during a silent web authentication that prevented the authentication - /// flow from completing in a short enough time frame. - /// - public static readonly string NoPromptFailedError = "no_prompt_failed"; - - /// - /// Initializes a new instance of the exception class with a specified - /// error code and error message. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - public MsalUiRequiredException(string errorCode, string errorMessage):base(errorCode, errorMessage) - { - } - - /// - /// Initializes a new instance of the exception class with a specified - /// error code, error message and inner exception indicating the root cause. - /// - /// - /// The error code returned by the service or generated by client. This is the code you can rely on - /// for exception handling. - /// - /// The error message that explains the reason for the exception. - /// Represents the root cause of the exception. - public MsalUiRequiredException(string errorCode, string errorMessage, Exception innerException):base(errorCode, errorMessage, innerException) - { - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta deleted file mode 100644 index 245b5fd..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/MsalUiRequiredException.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6e1a3424339a1b246abe59ac961b4f76 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta deleted file mode 100644 index 801c83b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 25b08f028a366be4b8696b6d36643a02 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta deleted file mode 100644 index abe612b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c0a1b7ac4cc22b64288a352174fa1c6f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs deleted file mode 100644 index 3497eb3..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs +++ /dev/null @@ -1,72 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -#if UNITY_EDITOR -using Microsoft.Identity.Client.Internal; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using System.Text; - -namespace Microsoft.Identity.Client -{ - internal class CryptographyHelper - { - public static string CreateBase64UrlEncodedSha256Hash(string input) - { - if (string.IsNullOrEmpty(input)) - { - return null; - } - - using (SHA256 sha = SHA256.Create()) - { - UTF8Encoding encoding = new UTF8Encoding(); - return Base64UrlHelpers.Encode(sha.ComputeHash(encoding.GetBytes(input))); - } - } - - public static string GenerateCodeVerifier() - { - byte[] buffer = new byte[Constants.CodeVerifierByteSize]; - using (var randomSource = RandomNumberGenerator.Create()) - { - randomSource.GetBytes(buffer); - } - - return Base64UrlHelpers.Encode(buffer); - } - - public byte[] SignWithCertificate(string message, X509Certificate2 certificate) - { - using (var key = certificate.GetRSAPrivateKey()) - { - return key.SignData(Encoding.UTF8.GetBytes(message), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } - } -} -#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta deleted file mode 100644 index 114d27d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/CryptographyHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ebad180b7ce78bf4b97090090bf0a6f5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs deleted file mode 100644 index 8257bff..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs +++ /dev/null @@ -1,66 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -#if UNITY_EDITOR -using Microsoft.Identity.Client.Internal; - -namespace Microsoft.Identity.Client -{ - internal class PlatformInformation : PlatformInformationBase - { - public PlatformInformation(RequestContext requestContext) : base(requestContext) - { - } - - public override string GetProductName() - { - return "MSAL.CoreCLR"; - } - - public override string GetEnvironmentVariable(string variable) - { - return null; - } - - public override string GetProcessorArchitecture() - { - return null; - } - - public override string GetOperatingSystem() - { - return System.Runtime.InteropServices.RuntimeInformation.OSDescription; - } - - public override string GetDeviceModel() - { - // Since MSAL .NET may be used on servers, for security reasons, we do not emit device type. - return null; - } - } -} -#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta deleted file mode 100644 index 07818b1..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/PlatformInformation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 542b74d785c1fd54bb398b8084f83475 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs deleted file mode 100644 index edbe3af..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs +++ /dev/null @@ -1,20 +0,0 @@ -#if UNITY_EDITOR -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Interfaces; -using System; -using System.Threading.Tasks; - -namespace Assets.Scripts.MSAL.Platforms.Unity -{ - internal class UnityWebUI - : IWebUI - { - public RequestContext RequestContext { get; set; } - - public Task AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext) - { - throw new NotImplementedException(); - } - } -} -#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta deleted file mode 100644 index 1ba2579..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/UnityWebUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c435d0d8f9d78a44c8b779b27a717aad -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs deleted file mode 100644 index b8c09ca..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs +++ /dev/null @@ -1,43 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -#if UNITY_EDITOR -using Assets.Scripts.MSAL.Platforms.Unity; -using Microsoft.Identity.Client.Internal.Interfaces; - -namespace Microsoft.Identity.Client.Internal.UI -{ - internal class WebUIFactory - : IWebUIFactory - { - public IWebUI CreateAuthenticationDialog(UIParent parent, RequestContext requestContext) - { - return new UnityWebUI(); - } - } -} -#endif \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta deleted file mode 100644 index 60dc56c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Platforms/Unity/WebUIFactory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ebb9b8ab681801c42a37fa1267106be9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta deleted file mode 100644 index 109328b..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b2bafeba7c24b7c41a60acbf3712e9f1 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs deleted file mode 100644 index fef8f59..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Text; - -// Allow this assembly to be serviced when run on desktop CLR -[assembly: AssemblyMetadata("Serviceable", "True")] - -[assembly: InternalsVisibleTo("XForms, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] -[assembly: InternalsVisibleTo("AutomationApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] -[assembly: InternalsVisibleTo("DesktopTestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] -[assembly: InternalsVisibleTo("Test.MSAL.NET.Unit, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta deleted file mode 100644 index dcb3a37..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/InternalsVisibleTo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 411421f03058bf74eb3532cbd582710b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml deleted file mode 100644 index 462f7be..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta deleted file mode 100644 index cbcb99c..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Properties/Microsoft.Identity.Client.rd.xml.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 703695d3c76fa5f449177800faee251c -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs deleted file mode 100644 index 58143ed..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs +++ /dev/null @@ -1,380 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Internal.Interfaces; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.Requests; -using System.Collections.Generic; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client -{ - /// - /// Class to be used for native applications (Desktop/UWP/iOS/Android). - /// - public sealed partial class PublicClientApplication : ClientApplicationBase, IPublicClientApplication - { - /// - /// Consutructor of the application. It will use https://login.microsoftonline.com/common as the default authority. - /// - /// Client id of the application - public PublicClientApplication(string clientId) : this(clientId, DefaultAuthority) - { - } - - /// - /// Consutructor of the application. - /// - /// Client id of the application - /// Default authority to be used for the application - public PublicClientApplication(string clientId, string authority) - : base(clientId, authority, PlatformPlugin.PlatformInformation.GetDefaultRedirectUri(clientId), true) - { - UserTokenCache = new TokenCache() - { - ClientId = clientId - }; - } - - -#if WINRT -/// -/// -/// - public bool UseCorporateNetwork { get; set; } -#endif - -#if !ANDROID - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, null, - UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScope).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, - UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScopeHint).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync( - IEnumerable scopes, - IUser user) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authority, scopes, null, user, - UIBehavior.SelectAccount, null, null, ApiEvent.ApiIds.AcquireTokenWithScopeUser).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, - UIBehavior behavior, string extraQueryParameters) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, - behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehavior).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, - UIBehavior behavior, string extraQueryParameters) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authority, scopes, null, user, behavior, - extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehavior).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, - UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authorityInstance, scopes, extraScopesToConsent, - loginHint, behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehaviorAuthority).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, - UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authorityInstance, scopes, extraScopesToConsent, user, - behavior, extraQueryParameters, null, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehaviorAuthority).ConfigureAwait(false); - } -#endif - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, UIParent parent) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, null, - UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScope).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, UIParent parent) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, - UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHint).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync( - IEnumerable scopes, - IUser user, UIParent parent) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authority, scopes, null, user, - UIBehavior.SelectAccount, null, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUser).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, - UIBehavior behavior, string extraQueryParameters, UIParent parent) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authority, scopes, null, loginHint, - behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehavior).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, - UIBehavior behavior, string extraQueryParameters, UIParent parent) - { - Authority authority = Internal.Instance.Authority.CreateAuthority(Authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authority, scopes, null, user, behavior, - extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehavior).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// Identifier of the user. Generally a UPN. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, string loginHint, - UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority, UIParent parent) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - return - await - AcquireTokenForLoginHintCommonAsync(authorityInstance, scopes, extraScopesToConsent, - loginHint, behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeHintBehaviorAuthority).ConfigureAwait(false); - } - - /// - /// Interactive request to acquire token. - /// - /// Array of scopes requested for resource - /// User object to enforce the same user to be authenticated in the web UI. - /// Enumeration to control UI behavior. - /// This parameter will be appended as is to the query string in the HTTP authentication request to the authority. The parameter can be null. - /// Array of scopes for which a developer can request consent upfront. - /// Specific authority for which the token is requested. Passing a different value than configured does not change the configured value - /// Object contains reference to parent window/activity. REQUIRED for Xamarin.Android only. - /// Authentication result containing token of the user - public async Task AcquireTokenAsync(IEnumerable scopes, IUser user, - UIBehavior behavior, string extraQueryParameters, IEnumerable extraScopesToConsent, string authority, UIParent parent) - { - Authority authorityInstance = Internal.Instance.Authority.CreateAuthority(authority, ValidateAuthority); - return - await - AcquireTokenForUserCommonAsync(authorityInstance, scopes, extraScopesToConsent, user, - behavior, extraQueryParameters, parent, ApiEvent.ApiIds.AcquireTokenWithScopeUserBehaviorAuthority).ConfigureAwait(false); - } - - - - internal IWebUI CreateWebAuthenticationDialog(UIParent parent, UIBehavior behavior, RequestContext requestContext) - { - //create instance of UIParent and assign useCorporateNetwork to UIParent - if (parent == null) - { - parent = new UIParent(); - } - -#if WINRT || DESKTOP - //hidden webview can be used in both WinRT and desktop applications. - parent.UseHiddenBrowser = behavior.Equals(UIBehavior.Never); -#if WINRT - parent.UseCorporateNetwork = UseCorporateNetwork; -#endif -#endif - - return PlatformPlugin.WebUIFactory.CreateAuthenticationDialog(parent, requestContext); - } - - private async Task AcquireTokenForLoginHintCommonAsync(Authority authority, IEnumerable scopes, - IEnumerable extraScopesToConsent, string loginHint, UIBehavior behavior, - string extraQueryParameters, UIParent parent, ApiEvent.ApiIds apiId) - { - var requestParams = CreateRequestParameters(authority, scopes, null, UserTokenCache); - requestParams.ExtraQueryParameters = extraQueryParameters; - var handler = - new InteractiveRequest(requestParams, extraScopesToConsent, loginHint, behavior, - CreateWebAuthenticationDialog(parent, behavior, requestParams.RequestContext)){ApiId = apiId}; - return await handler.RunAsync().ConfigureAwait(false); - } - - private async Task AcquireTokenForUserCommonAsync(Authority authority, IEnumerable scopes, - IEnumerable extraScopesToConsent, IUser user, UIBehavior behavior, string extraQueryParameters, UIParent parent, ApiEvent.ApiIds apiId) - { - - var requestParams = CreateRequestParameters(authority, scopes, user, UserTokenCache); - requestParams.ExtraQueryParameters = extraQueryParameters; - - var handler = - new InteractiveRequest(requestParams, extraScopesToConsent, behavior, - CreateWebAuthenticationDialog(parent, behavior, requestParams.RequestContext)){ApiId = apiId}; - return await handler.RunAsync().ConfigureAwait(false); - } - - internal override AuthenticationRequestParameters CreateRequestParameters(Authority authority, - IEnumerable scopes, IUser user, TokenCache cache) - { - AuthenticationRequestParameters parameters = base.CreateRequestParameters(authority, scopes, user, cache); - return parameters; - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta deleted file mode 100644 index 42ad553..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/PublicClientApplication.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 06a18977903d04243bcc9db801f1c76f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta deleted file mode 100644 index 803f041..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 66b849cf47d51ae4dbd3356fec82036f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt deleted file mode 100644 index 194ae28..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt +++ /dev/null @@ -1,50 +0,0 @@ -Images, layout descriptions, binary blobs and string dictionaries can be included -in your application as resource files. Various Android APIs are designed to -operate on the resource IDs instead of dealing with images, strings or binary blobs -directly. - -For example, a sample Android app that contains a user interface layout (main.xml), -an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) -would keep its resources in the "Resources" directory of the application: - -Resources/ - drawable-hdpi/ - icon.png - - drawable-ldpi/ - icon.png - - drawable-mdpi/ - icon.png - - layout/ - main.xml - - values/ - strings.xml - -In order to get the build system to recognize Android resources, set the build action to -"AndroidResource". The native Android APIs do not operate directly with filenames, but -instead operate on resource IDs. When you compile an Android application that uses resources, -the build system will package the resources for distribution and generate a class called -"Resource" that contains the tokens for each one of the resources included. For example, -for the above Resources layout, this is what the Resource class would expose: - -public class Resource { - public class drawable { - public const int icon = 0x123; - } - - public class layout { - public const int main = 0x456; - } - - public class strings { - public const int first_string = 0xabc; - public const int second_string = 0xbcd; - } -} - -You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main -to reference the layout/main.xml file, or Resource.strings.first_string to reference the first -string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta deleted file mode 100644 index 5c9afae..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/AboutResources.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9cdad3331fa45964ab9529b7198096db -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta deleted file mode 100644 index 16e5368..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ef36d6d15d17791409a4af9d5ed0c895 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml deleted file mode 100644 index b9c880f..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - $projectname$ - \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta deleted file mode 100644 index f5989e6..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/Values/Strings.xml.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: d2d03d9f0588c70468b3c6060ca584ef -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta deleted file mode 100644 index 8850014..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4af410608141b404bb11b1c540a3f131 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml deleted file mode 100644 index 13aaba7..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta deleted file mode 100644 index 9433f1a..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Resources/layout/WebAuthenticationBroker.axml.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: c013c8a9ada3f9245b88ffe7d7bba0b2 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs deleted file mode 100644 index 931fb9d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs +++ /dev/null @@ -1,209 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client -{ - /// - /// - /// - public class Telemetry - { - /// - /// - /// - /// - public delegate void Receiver(List> events); - - private Receiver _receiver = null; - - /// - /// - /// - /// - public void RegisterReceiver(Receiver r) - { - _receiver = r; - } - - private static readonly Telemetry Singleton = new Telemetry(); - - internal Telemetry(){} // This is an internal constructor to build isolated unit test instance - - /// - /// - /// - /// - public static Telemetry GetInstance() - { - return Singleton; - } - - /// - /// - /// - public bool TelemetryOnFailureOnly { get; set; } - - internal ConcurrentDictionary, EventBase> EventsInProgress = new ConcurrentDictionary, EventBase>(); - - internal ConcurrentDictionary> CompletedEvents = new ConcurrentDictionary>(); - - internal string GenerateNewRequestId() - { - return Guid.NewGuid().ToString(); - } - - internal void StartEvent(string requestId, EventBase eventToStart) - { - if (_receiver != null && requestId != null) - { - EventsInProgress[new Tuple(requestId, eventToStart[EventBase.EventNameKey])] = eventToStart; - } - } - - internal void StopEvent(string requestId, EventBase eventToStop) - { - if (_receiver == null || requestId == null) - { - return; - } - Tuple eventKey = new Tuple(requestId, eventToStop[EventBase.EventNameKey]); - - // Locate the same name event in the EventsInProgress map - EventBase eventStarted = null; - if (EventsInProgress.ContainsKey(eventKey)) - { - eventStarted = EventsInProgress[eventKey]; - } - - // If we did not get anything back from the dictionary, most likely its a bug that StopEvent - // was called without a corresponding StartEvent - if (null == eventStarted) - { - // Stop Event called without a corresponding start_event. - return; - } - - // Set execution time properties on the event - eventToStop.Stop(); - - if (!CompletedEvents.ContainsKey(requestId)) - { - // if this is the first event associated to this - // RequestId we need to initialize a new List to hold - // all of sibling events - List events = new List(); - events.Add(eventToStop); - CompletedEvents[requestId] = events; - } - else - { - // if this event shares a RequestId with other events - // just add it to the List - CompletedEvents[requestId].Add(eventToStop); - } - - // Mark this event as no longer in progress - EventBase dummy = null; // The TryRemove(...) next line requires an out parameter, even though we don't actually use it - EventsInProgress.TryRemove(eventKey, out dummy); - // We could use the following one-liner instead, but we believe it is less readable: - // ((IDictionary, EventBase>)EventsInProgress).Remove(eventKey); - } - - internal void Flush(string requestId) - { - if (_receiver == null) - { - return; - } - - // check for orphaned events... - List orphanedEvents = CollateOrphanedEvents(requestId); - // Add the OrphanedEvents to the completed EventList - if (!CompletedEvents.ContainsKey(requestId)) - { - // No completed Events returned for RequestId - return; - } - - CompletedEvents[requestId].AddRange(orphanedEvents); - - List eventsToFlush; - CompletedEvents.TryRemove(requestId, out eventsToFlush); - - if (TelemetryOnFailureOnly) - { - // iterate over Events, if the ApiEvent was successful, don't dispatch - bool shouldRemoveEvents = false; - - foreach (var anEvent in eventsToFlush) - { - var apiEvent = anEvent as ApiEvent; - if (apiEvent != null) - { - shouldRemoveEvents = apiEvent.WasSuccessful; - break; - } - } - - if (shouldRemoveEvents) - { - eventsToFlush.Clear(); - } - } - - if (eventsToFlush.Count > 0) - { - eventsToFlush.Insert(0, new DefaultEvent(ClientId)); - _receiver(eventsToFlush.Cast>().ToList()); - } - } - - private List CollateOrphanedEvents(String requestId) - { - var orphanedEvents = new List(); - foreach (var key in EventsInProgress.Keys) - { - if (key.Item1 == requestId) - { - // The orphaned event already contains its own start time, we simply collect it - EventBase orphan; - EventsInProgress.TryRemove(key, out orphan); - orphanedEvents.Add(orphan); - } - } - return orphanedEvents; - } - - internal string ClientId { get; set; } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta deleted file mode 100644 index efa595d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Telemetry.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ce92cff5e49405a44820cf40f204bab9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs deleted file mode 100644 index def51bc..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs +++ /dev/null @@ -1,752 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.Cache; -using Microsoft.Identity.Client.Internal.Instance; -using Microsoft.Identity.Client.Internal.OAuth2; -using Microsoft.Identity.Client.Internal.Requests; -using Microsoft.Identity.Client.Internal.Telemetry; - -namespace Microsoft.Identity.Client -{ - /// - /// Token cache class used by ConfidentialClientApplication and PublicClientApplication to store access and refresh tokens. - /// - public sealed class TokenCache - { - private const int DefaultExpirationBufferInMinutes = 5; - - internal readonly TelemetryTokenCacheAccessor TokenCacheAccessor = new TelemetryTokenCacheAccessor(); - - /// - /// Notification for certain token cache interactions during token acquisition. - /// - /// Arguments related to the cache item impacted - public delegate void TokenCacheNotification(TokenCacheNotificationArgs args); - - internal readonly object LockObject = new object(); - private volatile bool _hasStateChanged; - - internal string ClientId { get; set; } - - /// - /// Notification method called before any library method accesses the cache. - /// - internal TokenCacheNotification BeforeAccess { get; set; } - - /// - /// Notification method called before any library method writes to the cache. This notification can be used to reload - /// the cache state from a row in database and lock that row. That database row can then be unlocked in - /// AfterAccess notification. - /// - internal TokenCacheNotification BeforeWrite { get; set; } - - /// - /// Notification method called after any library method accesses the cache. - /// - internal TokenCacheNotification AfterAccess { get; set; } - - /// - /// Gets or sets the flag indicating whether cache state has changed. - /// MSAL methods set this flag after any change. - /// Caller application should reset the flag after serializing and persisting the state of the cache. - /// - public bool HasStateChanged - { - get { return _hasStateChanged; } - set { _hasStateChanged = value; } - } - - internal void OnAfterAccess(TokenCacheNotificationArgs args) - { - AfterAccess?.Invoke(args); - } - - internal void OnBeforeAccess(TokenCacheNotificationArgs args) - { - BeforeAccess?.Invoke(args); - } - - internal void OnBeforeWrite(TokenCacheNotificationArgs args) - { - HasStateChanged = true; - BeforeWrite?.Invoke(args); - } - - internal AccessTokenCacheItem SaveAccessAndRefreshToken(AuthenticationRequestParameters requestParams, - TokenResponse response) - { - lock (LockObject) - { - try - { - // create the access token cache item - AccessTokenCacheItem accessTokenCacheItem = - new AccessTokenCacheItem(requestParams.TenantUpdatedCanonicalAuthority, requestParams.ClientId, - response) - {UserAssertionHash = requestParams.UserAssertion?.AssertionHash}; - - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = accessTokenCacheItem.User - }; - - HasStateChanged = true; - OnBeforeAccess(args); - OnBeforeWrite(args); - - //delete all cache entries with intersecting scopes. - //this should not happen but we have this as a safe guard - //against multiple matches. - var msg = "Looking for scopes for the authority in the cache which intersect with " + - requestParams.Scope.AsSingleString(); - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - IList accessTokenItemList = new List(); - foreach (var accessTokenString in TokenCacheAccessor.GetAllAccessTokensAsString()) - { - AccessTokenCacheItem accessTokenItem = - JsonHelper.DeserializeFromJson(accessTokenString); - if (accessTokenItem.ClientId.Equals(ClientId) && - accessTokenItem.Authority.Equals(requestParams.TenantUpdatedCanonicalAuthority) && - accessTokenItem.ScopeSet.ScopeIntersects(accessTokenCacheItem.ScopeSet)) - { - msg = "Intersecting scopes found - " + accessTokenItem.Scope; - requestParams.RequestContext.Logger.Verbose(msg); - requestParams.RequestContext.Logger.VerbosePii(msg); - accessTokenItemList.Add(accessTokenItem); - } - } - - msg = "Intersecting scope entries count - " + accessTokenItemList.Count; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - - if (!requestParams.IsClientCredentialRequest) - { - //filter by identifer of the user instead - accessTokenItemList = - accessTokenItemList.Where( - item => item.GetUserIdentifier().Equals(accessTokenCacheItem.GetUserIdentifier())) - .ToList(); - msg = "Matching entries after filtering by user - " + accessTokenItemList.Count; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - } - - foreach (var cacheItem in accessTokenItemList) - { - TokenCacheAccessor.DeleteAccessToken(cacheItem.GetAccessTokenItemKey().ToString(), requestParams.RequestContext); - } - - TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), - JsonHelper.SerializeToJson(accessTokenCacheItem), requestParams.RequestContext); - - // if server returns the refresh token back, save it in the cache. - if (response.RefreshToken != null) - { - // create the refresh token cache item - RefreshTokenCacheItem refreshTokenCacheItem = new RefreshTokenCacheItem( - requestParams.Authority.Host, - requestParams.ClientId, - response); - msg = "Saving RT in cache..."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), - JsonHelper.SerializeToJson(refreshTokenCacheItem), requestParams.RequestContext); - } - - OnAfterAccess(args); - return accessTokenCacheItem; - } - finally - { - HasStateChanged = false; - } - } - } - - internal AccessTokenCacheItem FindAccessToken(AuthenticationRequestParameters requestParams) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheLookup) { TokenType = CacheEvent.TokenTypes.AT }; - Telemetry.GetInstance().StartEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); - try - { - return FindAccessTokenCommon(requestParams); - } - finally - { - Telemetry.GetInstance().StopEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); - } - } - - private AccessTokenCacheItem FindAccessTokenCommon(AuthenticationRequestParameters requestParams) - { - lock (LockObject) - { - string msg = "Looking up access token in the cache.."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - AccessTokenCacheItem accessTokenCacheItem = null; - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = requestParams.User - }; - - OnBeforeAccess(args); - //filtered by client id. - ICollection tokenCacheItems = GetAllAccessTokensForClient(requestParams.RequestContext); - OnAfterAccess(args); - - // this is OBO flow. match the cache entry with assertion hash, - // Authority, ScopeSet and client Id. - if (requestParams.UserAssertion != null) - { - msg = "Filtering by user assertion..."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - tokenCacheItems = - tokenCacheItems.Where( - item => - !string.IsNullOrEmpty(item.UserAssertionHash) && - item.UserAssertionHash.Equals(requestParams.UserAssertion.AssertionHash)) - .ToList(); - } - else - { - if (!requestParams.IsClientCredentialRequest) - { - msg = "Filtering by user identifier..."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - //filter by identifier of the user instead - tokenCacheItems = - tokenCacheItems - .Where(item => item.GetUserIdentifier().Equals(requestParams.User?.Identifier)) - .ToList(); - } - } - - //no match found after initial filtering - if (!tokenCacheItems.Any()) - { - msg = "No matching entry found for user or assertion"; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - return null; - } - - msg = "Matching entry count -" + tokenCacheItems.Count; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - - IEnumerable filteredItems = - tokenCacheItems.Where( - item => - item.ScopeSet.ScopeContains(requestParams.Scope)) - .ToList(); - - msg = "Matching entry count after filtering by scopes - " + filteredItems.Count(); - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - //no authority passed - if (requestParams.Authority == null) - { - msg = "No authority provided.."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - //if only one cached token found - if (filteredItems.Count() == 1) - { - accessTokenCacheItem = filteredItems.First(); - requestParams.Authority = - Authority.CreateAuthority(accessTokenCacheItem.Authority, requestParams.ValidateAuthority); - - msg = "1 matching entry found.Authority may be used for refreshing access token."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - } - else if (filteredItems.Count() > 1) - { - msg = "Multiple authorities found for same client_id, user and scopes"; - requestParams.RequestContext.Logger.Error(msg); - requestParams.RequestContext.Logger.ErrorPii(msg + " :- " + filteredItems - .Select(tci => tci.Authority) - .AsSingleString()); - throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, - MsalErrorMessage.MultipleTokensMatched); - } - else - { - msg = "No tokens found for matching client_id, user and scopes."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - - msg = "Check if the tokens are for the same authority for given client_id and user."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - //no match found. check if there was a single authority used - IEnumerable authorityList = tokenCacheItems.Select(tci => tci.Authority).Distinct(); - if (authorityList.Count() > 1) - { - msg = "Multiple authorities found for same client_id and user."; - requestParams.RequestContext.Logger.Error(msg); - requestParams.RequestContext.Logger.ErrorPii(msg + " :- " + authorityList.AsSingleString()); - - throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, - "Multiple authorities found in the cache. Pass in authority in the API overload."); - } - - msg = "Distinct Authority found. Use it for refresh token grant call"; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - requestParams.Authority = Authority.CreateAuthority(authorityList.First(), requestParams.ValidateAuthority); - } - } - else - { - msg = "Authority provided.."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - //authority was passed in the API - filteredItems = - filteredItems.Where( - item => - item.Authority.Equals(requestParams.Authority.CanonicalAuthority)) - .ToList(); - - //no match - if (!filteredItems.Any()) - { - msg = "No tokens found for matching authority, client_id, user and scopes."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - return null; - } - - //if only one cached token found - if (filteredItems.Count() == 1) - { - accessTokenCacheItem = filteredItems.First(); - } - else - { - msg = "Multiple tokens found for matching authority, client_id, user and scopes."; - requestParams.RequestContext.Logger.Error(msg); - requestParams.RequestContext.Logger.ErrorPii(msg); - - throw new MsalClientException(MsalClientException.MultipleTokensMatchedError, - MsalErrorMessage.MultipleTokensMatched); - } - } - - if (accessTokenCacheItem != null && accessTokenCacheItem.ExpiresOn > - DateTime.UtcNow + TimeSpan.FromMinutes(DefaultExpirationBufferInMinutes)) - { - msg = "Access token is not expired. Returning the found cache entry.."; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - return accessTokenCacheItem; - } - - if (accessTokenCacheItem != null) - { - msg = "Access token has expired or about to expire. Current time (" + DateTime.UtcNow + - ") - Expiration Time (" + accessTokenCacheItem.ExpiresOn + ")"; - requestParams.RequestContext.Logger.Info(msg); - requestParams.RequestContext.Logger.InfoPii(msg); - } - - return null; - } - } - - internal RefreshTokenCacheItem FindRefreshToken(AuthenticationRequestParameters requestParams) - { - var cacheEvent = new CacheEvent(CacheEvent.TokenCacheLookup) { TokenType = CacheEvent.TokenTypes.RT }; - Telemetry.GetInstance().StartEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); - try - { - return FindRefreshTokenCommon(requestParams); - } - finally - { - Telemetry.GetInstance().StopEvent(requestParams.RequestContext.TelemetryRequestId, cacheEvent); - } - } - - private RefreshTokenCacheItem FindRefreshTokenCommon(AuthenticationRequestParameters requestParam) - { - lock (LockObject) - { - var msg = "Looking up refresh token in the cache.."; - requestParam.RequestContext.Logger.Info(msg); - requestParam.RequestContext.Logger.InfoPii(msg); - if (requestParam.Authority == null) - { - return null; - } - - RefreshTokenCacheKey key = new RefreshTokenCacheKey( - requestParam.Authority.Host, requestParam.ClientId, - requestParam.User?.Identifier); - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = requestParam.User - }; - - OnBeforeAccess(args); - RefreshTokenCacheItem refreshTokenCacheItem = - JsonHelper.DeserializeFromJson( - TokenCacheAccessor.GetRefreshToken(key.ToString())); - OnAfterAccess(args); - - msg = "Refresh token found in the cache? - " + (refreshTokenCacheItem != null); - requestParam.RequestContext.Logger.Info(msg); - requestParam.RequestContext.Logger.InfoPii(msg); - return refreshTokenCacheItem; - } - } - - internal void DeleteRefreshToken(RefreshTokenCacheItem refreshTokenCacheItem) - { - lock (LockObject) - { - try - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = refreshTokenCacheItem.User - }; - - OnBeforeAccess(args); - OnBeforeWrite(args); - TokenCacheAccessor.DeleteRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString()); - OnAfterAccess(args); - } - finally - { - HasStateChanged = false; - } - } - } - - internal void DeleteAccessToken(AccessTokenCacheItem accessTokenCacheItem) - { - lock (LockObject) - { - try - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = accessTokenCacheItem.User - }; - - OnBeforeAccess(args); - OnBeforeWrite(args); - TokenCacheAccessor.DeleteAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString()); - OnAfterAccess(args); - } - finally - { - HasStateChanged = false; - } - } - } - - internal ICollection GetUsers(string environment, RequestContext requestContext) - { - lock (LockObject) - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = null - }; - - OnBeforeAccess(args); - ICollection tokenCacheItems = GetAllRefreshTokensForClient(requestContext); - OnAfterAccess(args); - - IDictionary allUsers = new Dictionary(); - foreach (RefreshTokenCacheItem item in tokenCacheItems) - { - if (environment.Equals( - item.Environment, StringComparison.OrdinalIgnoreCase)) - { - User user = new User(item.User); - allUsers[item.GetUserIdentifier()] = user; - } - } - - return allUsers.Values; - } - } - - internal ICollection GetAllRefreshTokensForClient(RequestContext requestContext) - { - lock (LockObject) - { - ICollection allRefreshTokens = new List(); - foreach (var refreshTokenString in TokenCacheAccessor.GetAllRefreshTokensAsString()) - { - RefreshTokenCacheItem refreshTokenCacheItem = - JsonHelper.DeserializeFromJson(refreshTokenString); - if (refreshTokenCacheItem.ClientId.Equals(ClientId)) - { - allRefreshTokens.Add(refreshTokenCacheItem); - } - } - - return allRefreshTokens; - } - } - - internal ICollection GetAllAccessTokensForClient(RequestContext requestContext) - { - lock (LockObject) - { - ICollection allAccessTokens = new List(); - foreach (var accessTokenString in TokenCacheAccessor.GetAllAccessTokensAsString()) - { - AccessTokenCacheItem accessTokenCacheItem = - JsonHelper.DeserializeFromJson(accessTokenString); - if (accessTokenCacheItem.ClientId.Equals(ClientId)) - { - allAccessTokens.Add(accessTokenCacheItem); - } - } - - return allAccessTokens; - } - } - - internal void Remove(IUser user, RequestContext requestContext) - { - lock (LockObject) - { - var msg = "Removing user from cache.."; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - - try - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = null - }; - - OnBeforeAccess(args); - OnBeforeWrite(args); - IList allRefreshTokens = GetAllRefreshTokensForClient(requestContext) - .Where(item => item.GetUserIdentifier().Equals(user.Identifier)) - .ToList(); - foreach (RefreshTokenCacheItem refreshTokenCacheItem in allRefreshTokens) - { - TokenCacheAccessor.DeleteRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), requestContext); - } - - msg = "Deleted refresh token count - " + allRefreshTokens.Count; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - IList allAccessTokens = GetAllAccessTokensForClient(requestContext) - .Where(item => item.GetUserIdentifier().Equals(user.Identifier)) - .ToList(); - - foreach (AccessTokenCacheItem accessTokenCacheItem in allAccessTokens) - { - TokenCacheAccessor.DeleteAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), requestContext); - } - - msg = "Deleted access token count - " + allAccessTokens.Count; - requestContext.Logger.Info(msg); - requestContext.Logger.InfoPii(msg); - OnAfterAccess(args); - } - finally - { - HasStateChanged = false; - } - } - } - - internal ICollection GetAllAccessTokenCacheItems(RequestContext requestContext) - { - // this method is called by serialize and does not require - // delegates because serialize itself is called from delegates - lock (LockObject) - { - ICollection allTokens = - TokenCacheAccessor.GetAllAccessTokensAsString(); - return allTokens; - } - } - - internal ICollection GetAllRefreshTokenCacheItems(RequestContext requestContext) - { - // this method is called by serialize and does not require - // delegates because serialize itself is called from delegates - lock (LockObject) - { - ICollection allTokens = - TokenCacheAccessor.GetAllRefreshTokensAsString(); - return allTokens; - } - } - - internal void AddAccessTokenCacheItem(AccessTokenCacheItem accessTokenCacheItem) - { - // this method is called by serialize and does not require - // delegates because serialize itself is called from delegates - lock (LockObject) - { - TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), - JsonHelper.SerializeToJson(accessTokenCacheItem)); - } - } - - internal void AddRefreshTokenCacheItem(RefreshTokenCacheItem refreshTokenCacheItem) - { - // this method is called by serialize and does not require - // delegates because serialize itself is called from delegates - lock (LockObject) - { - TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), - JsonHelper.SerializeToJson(refreshTokenCacheItem)); - } - } - - internal void ClearCache() - { - lock (LockObject) - { - try - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = null - }; - - OnBeforeAccess(args); - OnBeforeWrite(args); - - TokenCacheAccessor.Clear(); - - OnAfterAccess(args); - } - finally - { - HasStateChanged = false; - } - } - } - - /// - /// Only used by dev test apps - /// - /// - internal void SaveAccesTokenCacheItem(AccessTokenCacheItem accessTokenCacheItem) - { - lock (LockObject) - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = accessTokenCacheItem.User - }; - - try - { - HasStateChanged = true; - OnBeforeAccess(args); - OnBeforeWrite(args); - - TokenCacheAccessor.SaveAccessToken(accessTokenCacheItem.GetAccessTokenItemKey().ToString(), - JsonHelper.SerializeToJson(accessTokenCacheItem)); - } - finally - { - OnAfterAccess(args); - HasStateChanged = false; - } - } - } - - /// - /// Only used by dev test apps - /// - /// - internal void SaveRefreshTokenCacheItem(RefreshTokenCacheItem refreshTokenCacheItem) - { - lock (LockObject) - { - TokenCacheNotificationArgs args = new TokenCacheNotificationArgs - { - TokenCache = this, - ClientId = ClientId, - User = refreshTokenCacheItem.User - }; - - try - { - HasStateChanged = true; - OnBeforeAccess(args); - OnBeforeWrite(args); - - TokenCacheAccessor.SaveRefreshToken(refreshTokenCacheItem.GetRefreshTokenItemKey().ToString(), - JsonHelper.SerializeToJson(refreshTokenCacheItem)); - } - finally - { - OnAfterAccess(args); - HasStateChanged = false; - } - } - } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta deleted file mode 100644 index edc5e80..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCache.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6440d76bea7533a488c9efa9f0771d4b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs deleted file mode 100644 index f1586dd..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs +++ /dev/null @@ -1,50 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Identity.Client -{ - /// - /// Contains parameters used by the MSAL call accessing the cache. - /// - public sealed class TokenCacheNotificationArgs - { - /// - /// Gets the TokenCache - /// - public TokenCache TokenCache { get; internal set; } - - /// - /// Gets the ClientId. - /// - public string ClientId { get; internal set; } - - /// - /// Gets the user object. - /// - public IUser User { get; internal set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta deleted file mode 100644 index fc75c62..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/TokenCacheNotificationArgs.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 07824183ca3a9bb4a8d1f140b647055c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs deleted file mode 100644 index 38ac2e6..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs +++ /dev/null @@ -1,111 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.Identity.Client -{ - /// - /// Indicates how AcquireToken should prompt the user. - /// - public partial struct UIBehavior - { - /// - /// AcquireToken will send prompt=select_account to authorize endpoint - /// and would show a list of users from which one can be selected for - /// authentication. - /// - public static readonly UIBehavior SelectAccount = new UIBehavior("select_account"); - - /// - /// The user will be prompted for credentials by the service. It is achieved - /// by sending prompt=login to the service. - /// - public static readonly UIBehavior ForceLogin = new UIBehavior("login"); - - /// - /// The user will be prompted to consent even if consent was granted before. It is achieved - /// by sending prompt=consent to the service. - /// - public static readonly UIBehavior Consent = new UIBehavior("consent"); - - -#if NET45 || WINRT - /// - /// Only available on .NET platform. AcquireToken will send prompt=attempt_none to - /// authorize endpoint and the library uses a hidden webview to authenticate the user. - /// - public static readonly UIBehavior Never = new UIBehavior("attempt_none"); -#endif - - internal string PromptValue { get; } - - private UIBehavior(string promptValue) - { - PromptValue = promptValue; - } - - /// - /// Equals method override to compare UIBehavior structs - /// - /// object to compare against - /// true if object are equal. - public override bool Equals(object obj) - { - return obj is UIBehavior && this == (UIBehavior)obj; - } - - /// - /// Override to compute hashcode - /// - /// hash code of the PromptValue - public override int GetHashCode() - { - return PromptValue.GetHashCode(); - } - - /// - /// operator overload to equality check - /// - /// first value - /// second value - /// true if the object are equal - public static bool operator ==(UIBehavior x, UIBehavior y) - { - return x.PromptValue == y.PromptValue; - } - - /// - /// operator overload to equality check - /// - /// first value - /// second value - /// true if the object are not equal - public static bool operator !=(UIBehavior x, UIBehavior y) - { - return !(x == y); - } - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta deleted file mode 100644 index 0fd8853..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIBehavior.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 22bd2dcd5d490ec4c8b6ffa2912f4d78 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs deleted file mode 100644 index 094f46f..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs +++ /dev/null @@ -1,88 +0,0 @@ -//---------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -#if ANDROID -using System; -using Android.App; -#endif - - -namespace Microsoft.Identity.Client -{ - /// - /// - /// - public sealed class UIParent - { - /// - /// Default constructor. - /// - public UIParent() - { - } - -#if ANDROID - internal Activity Activity { get; set; } - - /// - /// Initializes an instance for a provided activity. - /// - /// parent activity for the call. REQUIRED. - public UIParent(Activity activity) - { - if(activity == null) - { - throw new ArgumentException("passed in activity is null", nameof(activity)); - } - - Activity = activity; - } -#endif - -#if DESKTOP || WINRT - //hidden webview can be used in both WinRT and desktop applications. - internal bool UseHiddenBrowser { get; set; } - -#if WINRT - internal bool UseCorporateNetwork { get; set; } -#endif - -#if DESKTOP - internal object OwnerWindow { get; set; } - - /// - /// Initializes an instance for a provided parent window. - /// - /// Parent window object reference. OPTIONAL. - public UIParent(object ownerWindow) - { - OwnerWindow = ownerWindow; - } -#endif -#endif - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta deleted file mode 100644 index 6e40ff4..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UIParent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ba9caa8db412a4c4c83ed9f74c8cff9a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs deleted file mode 100644 index 7b93030..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs +++ /dev/null @@ -1,79 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; - -namespace Microsoft.Identity.Client -{ - /// - /// Contains information of a single user. This information is used for token cache lookup and enforcing the user session on STS authorize endpont. - /// - internal sealed class User: IUser - { - public User() - { - } - - internal User(User other) - { - DisplayableId = other.DisplayableId; - Identifier = other.Identifier; - Name = other.Name; - IdentityProvider = other.IdentityProvider; - } - - public User(string identifier, string displayableId, string name, string identityProvider) - { - if (string.IsNullOrWhiteSpace(identifier)) - { - throw new ArgumentNullException(nameof(identifier)); - } - - DisplayableId = displayableId; - Name = name; - IdentityProvider = identityProvider; - Identifier = identifier; - } - - /// - /// Gets a displayable value in UserPrincipalName (UPN) format. The value can be null. - /// - public string DisplayableId { get; internal set; } - - /// - /// Gets given name of the user if provided by the service. If not, the value is null. - /// - public string Name { get; internal set; } - - /// - /// Gets identity provider if returned by the service. If not, the value is null. - /// - public string IdentityProvider { get; internal set; } - - public string Identifier { get; internal set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta deleted file mode 100644 index 694a32e..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/User.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 92fb77610f826264bb5a20d6ccfcd9f4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs deleted file mode 100644 index 138ad51..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs +++ /dev/null @@ -1,84 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. -// All rights reserved. -// -// This code is licensed under the MIT License. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -//------------------------------------------------------------------------------ - -using System; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.Internal.OAuth2; - -namespace Microsoft.Identity.Client -{ - /// - /// Credential type containing an assertion representing user credential. - /// - public sealed class UserAssertion - { - /// - /// Constructor to create the object with an assertion. This constructor can be used for On Behalf Of flow which - /// assumes the - /// assertion is a JWT token. For other flows, the other construction with assertionType must be used. - /// - /// Assertion representing the user. - public UserAssertion(string assertion) : this(assertion, OAuth2GrantType.JwtBearer) - { - } - - /// - /// Constructor to create credential with assertion and assertionType - /// - /// Assertion representing the user. - /// Type of the assertion representing the user. - public UserAssertion(string assertion, string assertionType) - { - if (string.IsNullOrWhiteSpace(assertion)) - { - throw new ArgumentNullException(nameof(assertion)); - } - - if (string.IsNullOrWhiteSpace(assertionType)) - { - throw new ArgumentNullException(nameof(assertionType)); - } - - AssertionType = assertionType; - Assertion = assertion; - AssertionHash = - CryptographyHelper.CreateBase64UrlEncodedSha256Hash(Assertion); - } - - /// - /// Gets the assertion. - /// - public string Assertion { get; private set; } - - /// - /// Gets the assertion type. - /// - public string AssertionType { get; private set; } - - internal string AssertionHash { get; set; } - } -} \ No newline at end of file diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta deleted file mode 100644 index e85a53d..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/UserAssertion.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 21bbc1b8b9aee85449d2d9030fb75720 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models.meta similarity index 77% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Models.meta index d78f25b..03905bd 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b435e57a2dbeeac499427a58f1d15e36 +guid: e038a5b4c9767bb40a7ed4e510035955 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs new file mode 100644 index 0000000..547d1cc --- /dev/null +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs @@ -0,0 +1,17 @@ +namespace Assets.Scripts.Models +{ + public class IdentityResult + { + public string token_type { get; set; } + public string scope { get; set; } + public string expires_in { get; set; } + public string ext_expires_in { get; set; } + public string expires_on { get; set; } + public string not_before { get; set; } + public string resource { get; set; } + public string access_token { get; set; } + public string refresh_token { get; set; } + public string id_token { get; set; } + } + +} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs.meta similarity index 83% rename from Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta rename to Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs.meta index 24cf2c2..0a43440 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/Microsoft.Identity.Client/Features/ConfidentialClient/ClientAssertionCertificate.cs.meta +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/Models/IdentityResult.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5c9f6f3f7b8883242a53a4ceb687510b +guid: c0d860f79f7a6eb4faa5adc201e822da MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs deleted file mode 100644 index 3a06c97..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Assets.Scripts -{ - public static class ServiceLocator - { - private static IDictionary InternalServices = new Dictionary(); - - public static void RegisterService(Action> registrationCallback) - { - registrationCallback(InternalServices); - } - - public static T GetService() - { - try - { - return (T)InternalServices[typeof(T)]; - } - catch (KeyNotFoundException) - { - throw new ApplicationException("The requested service is not registered"); - } - } - - } -} diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta b/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta deleted file mode 100644 index b557637..0000000 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/ServiceLocator.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b894f2f07e31bcd49ac3a73d7507c2aa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs index 589d457..7295471 100644 --- a/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs +++ b/Standalone-Samples/Unity-Identity/Assets/Scripts/StartupScript.cs @@ -1,35 +1,82 @@ -using Microsoft.Identity.Client; +using Assets.Scripts.Models; +using Newtonsoft.Json; +using System; +using System.Collections; using System.Collections.Generic; -using System.Linq; +using System.Net.Http; using UnityEngine; public class StartupScript : MonoBehaviour { - public GameObject UnityWebBrowser; + public string ClientId; + + public string ClientSecret; + + public string TenantId; // Use this for initialization void Start() { - var clientId = "2437fe4e-b874-48ec-b3ee-e6658f6abdb9"; - var scopes = new List() + // TODO: use secure string... + var username = "testuser@jwendl.net"; + var password = ""; + + StartCoroutine(Authenticate((identityResult) => { - "User.Read", - }; + // Update UI here... + }, username, password)); - var publicClientApplication = new PublicClientApplication(clientId); - var user = publicClientApplication.Users.FirstOrDefault(); + //var scopes = new List() + //{ + // "User.Read", + //}; - if (user == default(User)) - { - // No user in token cache - var authenticationResult = publicClientApplication.AcquireTokenAsync(scopes).Result; - } - else + //var publicClientApplication = new PublicClientApplication(clientId); + //var user = publicClientApplication.Users.FirstOrDefault(); + + //if (user == default(User)) + //{ + // // No user in token cache + // var authenticationResult = publicClientApplication.AcquireTokenAsync(scopes).Result; + //} + //else + //{ + // // Call out to UI to get username and password + // var authenticationResult = publicClientApplication.AcquireTokenSilentAsync(scopes, user).Result; + //} + } + + IEnumerator Authenticate(Action identityCallback, string username, string password) + { + var resource = "https://graph.microsoft.com"; + // TODO: these two are public properties so they are entered in unity UI? + + var grantType = "password"; + var scope = "openid"; + + var formContent = new FormUrlEncodedContent(new[] { - // Call out to UI to get username and password - var authenticationResult = publicClientApplication.AcquireTokenSilentAsync(scopes, user).Result; - } + new KeyValuePair("resource", resource), + new KeyValuePair("client_id", ClientId), + new KeyValuePair("client_secret", ClientSecret), + new KeyValuePair("grant_type", grantType), + new KeyValuePair("username", username), + new KeyValuePair("password", password), + new KeyValuePair("scope", scope), + }); + + var httpClient = new HttpClient(); + var httpResponseMessageTask = httpClient.PostAsync($"https://login.windows.net/{TenantId}/oauth2/token", formContent); + var jsonTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync(); + + // Below doesn't work because their deserializer expects numbers to be 3 instead of "3"... + //var identityResult = JsonUtility.FromJson(jsonTask.Result); + var identityResult = JsonConvert.DeserializeObject(jsonTask.Result); + + yield return new WaitUntil(() => true); + + identityCallback(identityResult); } // Update is called once per frame From 34a3cfa409cb4c792ea6e69cab617cb5dee7ad0a Mon Sep 17 00:00:00 2001 From: Justin Wendlandt Date: Wed, 25 Jul 2018 17:30:58 -0700 Subject: [PATCH 5/5] Building SDK Code --- .../Assembly-CSharp-Editor.csproj | 1284 +++++++++-------- .../Assembly-CSharp.csproj | 1185 +++++++-------- .../Assets/MixedRealityAzure/Azure AD.meta | 8 + .../Azure AD/AzureAuthentication.cs | 82 ++ .../Azure AD/AzureAuthentication.cs.meta | 11 + .../MixedRealityAzure/Azure AD/Models.meta | 8 + .../Azure AD/Models/IdentityResult.cs | 16 + .../Azure AD/Models/IdentityResult.cs.meta | 11 + .../MixedReality-Azure-Unity.sln | 34 +- .../ProjectSettings/ProjectVersion.txt | 2 +- 10 files changed, 1416 insertions(+), 1225 deletions(-) create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD.meta create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs.meta create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models.meta create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs create mode 100644 Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs.meta diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp-Editor.csproj b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp-Editor.csproj index e7cb072..ae376af 100644 --- a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp-Editor.csproj +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp-Editor.csproj @@ -13,7 +13,7 @@ Library Properties Assembly-CSharp-Editor - v4.6 + v4.7.1 512 . @@ -22,7 +22,7 @@ full false Temp\bin\Debug\ - DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_1_0;UNITY_2018_1;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_PLAYMODE_TESTS_RUNNER;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;DEVELOPMENT_BUILD;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;UNITY_TEAM_LICENSE;ENABLE_MONO + DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_2_0;UNITY_2018_2;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_TEXTURE_STREAMING;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE;ENABLE_MONO prompt 4 0169 @@ -41,635 +41,680 @@ true true false + false + false + + + {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Unity/VSTU + Editor:5 + StandaloneWindows64:19 + 2018.2.0x-ImprovedPrefabs - C:\Program Files\Unity\Hub\Editor\2018.1.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll - C:\Program Files\Unity\Hub\Editor\2018.1.0f2\Editor\Data\Managed/UnityEditor.dll + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEditor.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticlesLegacyModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpatialTrackingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WebModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/Unity.Locator.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/Editor/UnityEditor.UI.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Networking/Editor/UnityEditor.Networking.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/Editor/UnityEditor.TestRunner.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/UnityEngine.TestRunner.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/net35/unity-custom/nunit.framework.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Timeline/Editor/UnityEditor.Timeline.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/TreeEditor/Editor/UnityEditor.TreeEditor.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UIAutomation/UnityEngine.UIAutomation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UIAutomation/Editor/UnityEditor.UIAutomation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/Editor/UnityEditor.GoogleAudioSpatializer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/Editor/UnityEditor.HoloLens.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/Editor/UnityEditor.SpatialTracking.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEditor.Graphs.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/PlaybackEngines/AndroidPlayer/UnityEditor.Android.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/PlaybackEngines/MetroSupport/UnityEditor.WSA.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/PlaybackEngines/windowsstandalonesupport/UnityEditor.WindowsStandalone.Extensions.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/LUIS/net45+win8+wpa81/Microsoft.Cognitive.LUIS.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/Newtonsoft.Json/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.ads@2.0.7/Editor/UnityEditor.Advertisements.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/Editor/UnityEditor.Analytics.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/Editor/UnityEditor.Purchasing.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll - + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.TextMeshPro.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticlesLegacyModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpatialTrackingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/Unity.Locator.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/Editor/UnityEditor.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/Editor/UnityEditor.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/Editor/UnityEditor.TestRunner.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/UnityEngine.TestRunner.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TestRunner/net35/unity-custom/nunit.framework.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/Editor/UnityEditor.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/TreeEditor/Editor/UnityEditor.TreeEditor.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/Editor/UnityEditor.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/Editor/UnityEditor.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/Editor/UnityEditor.SpatialTracking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityVR/Editor/UnityEditor.VR.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEditor.Graphs.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/AndroidPlayer/UnityEditor.Android.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/MetroSupport/UnityEditor.WSA.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/WebGLSupport/UnityEditor.WebGL.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/windowsstandalonesupport/UnityEditor.WindowsStandalone.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/MacStandaloneSupport/UnityEditor.OSXStandalone.Extensions.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/LUIS/net45+win8+wpa81/Microsoft.Cognitive.LUIS.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/Newtonsoft.Json/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.ads@2.0.8/Editor/UnityEditor.Advertisements.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/Editor/UnityEditor.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/Editor/UnityEditor.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll + + + C:/Program Files (x86)/Microsoft Visual Studio Tools for Unity/15.0/Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Xcode.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Core.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Runtime.Serialization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Xml.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/System.Numerics.Vectors.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/Microsoft.Win32.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/netstandard.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.AppContext.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Concurrent.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.NonGeneric.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Collections.Specialized.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Annotations.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.EventBasedAsync.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ComponentModel.TypeConverter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Console.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Data.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Contracts.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Debug.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.FileVersionInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.StackTrace.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TextWriterTraceListener.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.Tools.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Diagnostics.TraceSource.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Drawing.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Dynamic.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Calendars.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Globalization.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Compression.ZipFile.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.DriveInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.FileSystem.Watcher.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.IsolatedStorage.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.MemoryMappedFiles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.Pipes.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.IO.UnmanagedMemoryStream.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Expressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Linq.Queryable.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Http.Rtc.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NameResolution.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.NetworkInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Ping.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Requests.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.Sockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebHeaderCollection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.Client.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Net.WebSockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ObjectModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.ILGeneration.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Emit.Lightweight.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Reflection.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Reader.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.ResourceManager.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Resources.Writer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.CompilerServices.VisualC.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Handles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.RuntimeInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.InteropServices.WindowsRuntime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Formatters.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Json.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Runtime.Serialization.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Claims.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Algorithms.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Csp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Cryptography.X509Certificates.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.Principal.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Security.SecureString.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Duplex.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Http.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.NetTcp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ServiceModel.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.Encoding.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Text.RegularExpressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Overlapped.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Tasks.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Thread.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.ThreadPool.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Threading.Timer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.ValueTuple.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.ReaderWriter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XmlSerializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/Facades/System.Xml.XPath.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/UnityScript.Lang.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/MonoBleedingEdge/lib/mono/unityscript/Boo.Lang.dll + - {6208DB9F-F8AC-EBCB-7B18-67F4C4065086} Assembly-CSharp + {6208DB9F-F8AC-EBCB-7B18-67F4C4065086} + Assembly-CSharp + + - - + \ No newline at end of file diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp.csproj b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp.csproj index 3544953..e7eb787 100644 --- a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp.csproj +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assembly-CSharp.csproj @@ -13,7 +13,7 @@ Library Properties Assembly-CSharp - v4.6 + v4.7.1 512 . @@ -22,7 +22,7 @@ full false Temp\bin\Debug\ - DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_1_0;UNITY_2018_1;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_PLAYMODE_TESTS_RUNNER;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;DEVELOPMENT_BUILD;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;UNITY_TEAM_LICENSE;ENABLE_MONO + DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_2_0;UNITY_2018_2;UNITY_2018;PLATFORM_ARCH_64;UNITY_64;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_SPRITES;ENABLE_GRID;ENABLE_TILEMAP;ENABLE_TERRAIN;ENABLE_TEXTURE_STREAMING;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_VIDEO;ENABLE_PACKMAN;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_LOCALIZATION;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_EVENT_QUEUE;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;ENABLE_VR;ENABLE_AR;ENABLE_WEBSOCKET_HOST;ENABLE_IL2CPP;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE;ENABLE_MONO prompt 4 0169 @@ -41,593 +41,617 @@ true true false + false + false + + + {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Unity/VSTU + Game:1 + StandaloneWindows64:19 + 2018.2.0x-ImprovedPrefabs - C:\Program Files\Unity\Hub\Editor\2018.1.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEngine/UnityEngine.dll - C:\Program Files\Unity\Hub\Editor\2018.1.0f2\Editor\Data\Managed/UnityEditor.dll + C:\Program Files\Unity\Hub\Editor\2018.2.0f2\Editor\Data\Managed/UnityEditor.dll - - - - - - - - - - - - - - - - - - - - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticlesLegacyModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpatialTrackingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WebModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/Managed/Unity.Locator.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UIAutomation/UnityEngine.UIAutomation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/LUIS/net45+win8+wpa81/Microsoft.Cognitive.LUIS.dll - - - C:/Users/jbienz/Code/Microsoft/MixedReality-Azure-Samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/Newtonsoft.Json/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll - - - C:/Users/jbienz/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/ref/2.0.0/netstandard.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/Microsoft.Win32.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.AppContext.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Concurrent.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.NonGeneric.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Specialized.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.EventBasedAsync.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.TypeConverter.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Console.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Data.Common.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Contracts.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Debug.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.FileVersionInfo.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Process.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.StackTrace.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TextWriterTraceListener.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tools.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TraceSource.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tracing.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Drawing.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Dynamic.Runtime.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Calendars.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.ZipFile.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.DriveInfo.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Watcher.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.IsolatedStorage.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.MemoryMappedFiles.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Pipes.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.UnmanagedMemoryStream.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Expressions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Parallel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Queryable.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Http.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NameResolution.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NetworkInformation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Ping.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Requests.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Security.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Sockets.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebHeaderCollection.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.Client.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ObjectModel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Reader.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.ResourceManager.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Writer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.CompilerServices.VisualC.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Handles.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.RuntimeInformation.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Numerics.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Formatters.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Json.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Xml.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Claims.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Algorithms.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Csp.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Encoding.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Primitives.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.X509Certificates.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Principal.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.SecureString.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.Extensions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.RegularExpressions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Overlapped.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.Parallel.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Thread.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.ThreadPool.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Timer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ValueTuple.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.ReaderWriter.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlSerializer.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.XDocument.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/mscorlib.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ComponentModel.Composition.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Core.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Data.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Drawing.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.IO.Compression.FileSystem.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Net.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Numerics.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Runtime.Serialization.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ServiceModel.Web.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Transactions.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Web.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Windows.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Linq.dll - - - C:/Program Files/Unity/Hub/Editor/2018.1.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Serialization.dll - + + + + + + + + + + + + + + + + + + + + + + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/UnityEditor.StandardEvents.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.TextMeshPro.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.PackageManagerUI.Editor.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Library/ScriptAssemblies/Unity.TextMeshPro.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ARModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AccessibilityModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AnimationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.AudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.BaselibModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClothModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CloudWebServicesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterInputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ClusterRendererModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.CrashReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.DirectorModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FacebookModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.FileSystemHttpModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GameCenterModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.GridModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.HotReloadModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.IMGUIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ImageConversionModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.InputModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.JSONSerializeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.LocalizationModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ParticleSystemModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PerformanceReportingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.PhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.Physics2DModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ProfilerModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.ScreenCaptureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SharedInternalsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteMaskModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SpriteShapeModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StreamingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.StyleSheetsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.SubstanceModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TLSModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TerrainPhysicsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TextRenderingModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TilemapModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.TimelineModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UIElementsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UNETModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UmbraModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityAnalyticsModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityConnectModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAssetBundleModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestAudioModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestTextureModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.UnityWebRequestWWWModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VehiclesModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.VideoModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.WindModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/UnityEngine/UnityEngine.XRModule.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/Managed/Unity.Locator.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityGoogleAudioSpatializer/RuntimeEditor/UnityEngine.GoogleAudioSpatializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/UnityExtensions/Unity/UnitySpatialTracking/RuntimeEditor/UnityEngine.SpatialTracking.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/LUIS/net45+win8+wpa81/Microsoft.Cognitive.LUIS.dll + + + C:/Source/GitHub/mixedreality-azure-samples/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/Plugins/Newtonsoft.Json/portable-net45+wp80+win8+wpa81/Newtonsoft.Json.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.analytics@2.0.16/UnityEngine.Analytics.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.purchasing@2.0.1/UnityEngine.Purchasing.dll + + + C:/Users/juswen/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.standardevents@1.0.13/UnityEngine.StandardEvents.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/ref/2.0.0/netstandard.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/Microsoft.Win32.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.AppContext.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Concurrent.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.NonGeneric.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Collections.Specialized.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.EventBasedAsync.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ComponentModel.TypeConverter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Console.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Data.Common.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Contracts.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Debug.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.FileVersionInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Process.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.StackTrace.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TextWriterTraceListener.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tools.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.TraceSource.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Diagnostics.Tracing.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Drawing.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Dynamic.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Calendars.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Globalization.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Compression.ZipFile.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.DriveInfo.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.FileSystem.Watcher.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.IsolatedStorage.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.MemoryMappedFiles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.Pipes.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.IO.UnmanagedMemoryStream.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Expressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Linq.Queryable.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Http.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NameResolution.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.NetworkInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Ping.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Requests.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Security.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.Sockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebHeaderCollection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.Client.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Net.WebSockets.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ObjectModel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Reflection.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Reader.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.ResourceManager.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Resources.Writer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.CompilerServices.VisualC.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Handles.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.InteropServices.RuntimeInformation.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Formatters.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Json.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Runtime.Serialization.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Claims.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Algorithms.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Csp.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.Primitives.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Cryptography.X509Certificates.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.Principal.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Security.SecureString.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.Encoding.Extensions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Text.RegularExpressions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Overlapped.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Tasks.Parallel.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Thread.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.ThreadPool.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Threading.Timer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.ValueTuple.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.ReaderWriter.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XmlSerializer.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netstandard/System.Xml.XPath.XDocument.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/Extensions/2.0.0/System.Numerics.Vectors.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/Extensions/2.0.0/System.Runtime.InteropServices.WindowsRuntime.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/mscorlib.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ComponentModel.Composition.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Core.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Data.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Drawing.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.IO.Compression.FileSystem.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Net.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Numerics.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Runtime.Serialization.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.ServiceModel.Web.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Transactions.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Web.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Windows.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Linq.dll + + + C:/Program Files/Unity/Hub/Editor/2018.2.0f2/Editor/Data/NetStandard/compat/2.0.0/shims/netfx/System.Xml.Serialization.dll + + - - + \ No newline at end of file diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD.meta b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD.meta new file mode 100644 index 0000000..a914fb8 --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c6f013db8dc8c484c840cb917ee6430d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs new file mode 100644 index 0000000..75ebbaf --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs @@ -0,0 +1,82 @@ +using Assets.MixedRealityAzure.AzureAD.Models; +using Microsoft.MR; +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net.Http; +using UnityEngine; + +public class AzureAuthentication + : MonoBehaviour +{ + [Tooltip("The application ID from Azure AD.")] + [SecretValue("AAD.ClientId")] + public string ClientId; + + [Tooltip("The client secret for the application.")] + [SecretValue("AAD.ClientSecret")] + public string ClientSecret; + + [Tooltip("The tenant ID for AAD.")] + [SecretValue("AAD.TenantId")] + public string TenantId; + + [Tooltip("The resource name like https://graph.microsoft.com.")] + [SecretValue("AAD.Resource")] + public string Resource; + + [Tooltip("The user's Username.")] + [SecretValue("AAD.Username")] + public string Username; + + [Tooltip("The user's password.")] + [SecretValue("AAD.Password")] + public string Password; + + // Use this for initialization + void Start() + { + StartCoroutine(Authenticate((identityResult) => + { + // Update UI here... + + // Call out to other service using identityResult.access_token + })); + } + + IEnumerator Authenticate(Action identityCallback) + { + var grantType = "password"; + var scope = "openid"; + + var formContent = new FormUrlEncodedContent(new[] + { + new KeyValuePair("resource", Resource), + new KeyValuePair("client_id", ClientId), + new KeyValuePair("client_secret", ClientSecret), + new KeyValuePair("grant_type", grantType), + new KeyValuePair("username", Username), + new KeyValuePair("password", Password), + new KeyValuePair("scope", scope), + }); + + var httpClient = new HttpClient(); + var httpResponseMessageTask = httpClient.PostAsync($"https://login.windows.net/{TenantId}/oauth2/token", formContent); + var jsonTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync(); + + // Below doesn't work because their deserializer expects numbers to be 3 instead of "3"... + //var identityResult = JsonUtility.FromJson(jsonTask.Result); + var identityResult = JsonConvert.DeserializeObject(jsonTask.Result); + + yield return new WaitUntil(() => true); + + identityCallback(identityResult); + } + + // Update is called once per frame + void Update() + { + + } +} diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs.meta b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs.meta new file mode 100644 index 0000000..f869e94 --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/AzureAuthentication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a436c6fb9ddded4498b8a020c9d96724 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models.meta b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models.meta new file mode 100644 index 0000000..3d34b0c --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 555017dcbd9cafc4c8785ffc91bc5ed3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs new file mode 100644 index 0000000..3af336b --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs @@ -0,0 +1,16 @@ +namespace Assets.MixedRealityAzure.AzureAD.Models +{ + public class IdentityResult + { + public string token_type { get; set; } + public string scope { get; set; } + public string expires_in { get; set; } + public string ext_expires_in { get; set; } + public string expires_on { get; set; } + public string not_before { get; set; } + public string resource { get; set; } + public string access_token { get; set; } + public string refresh_token { get; set; } + public string id_token { get; set; } + } +} diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs.meta b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs.meta new file mode 100644 index 0000000..fc65339 --- /dev/null +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/Assets/MixedRealityAzure/Azure AD/Models/IdentityResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 849a39e8bd5951d44a5a31fb4307561d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/MixedReality-Azure-Unity.sln b/Reference-Architecture/Client/MixedReality-Azure-Unity/MixedReality-Azure-Unity.sln index e723652..745fa70 100644 --- a/Reference-Architecture/Client/MixedReality-Azure-Unity/MixedReality-Azure-Unity.sln +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/MixedReality-Azure-Unity.sln @@ -1,13 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2017 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MixedReality-Azure-Unity", "MixedReality-Azure-Unity.csproj", "{4440C6AA-B958-1E90-8BF6-9741696C9C4A}" +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MixedReality-Azure-Unity", "Assembly-CSharp.csproj", "{6208DB9F-F8AC-EBCB-7B18-67F4C4065086}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.PackageManagerUI.Editor", "Unity.PackageManagerUI.Editor.csproj", "{6877705C-FBD9-0C4F-5AFB-6FB431E5D39D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MixedReality-Azure-Unity.Editor", "MixedReality-Azure-Unity.Editor.csproj", "{A7775F69-050F-CC87-3441-23EDC710AFFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEditor.StandardEvents", "UnityEditor.StandardEvents.csproj", "{6800202F-4402-D405-F8CB-03DC7BD78B92}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MixedReality-Azure-Unity", "Assembly-CSharp-Editor.csproj", "{EDA4797C-B86C-95C4-91A7-0692260042EB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,22 +11,14 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4440C6AA-B958-1E90-8BF6-9741696C9C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4440C6AA-B958-1E90-8BF6-9741696C9C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4440C6AA-B958-1E90-8BF6-9741696C9C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4440C6AA-B958-1E90-8BF6-9741696C9C4A}.Release|Any CPU.Build.0 = Release|Any CPU - {6877705C-FBD9-0C4F-5AFB-6FB431E5D39D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6877705C-FBD9-0C4F-5AFB-6FB431E5D39D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6877705C-FBD9-0C4F-5AFB-6FB431E5D39D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6877705C-FBD9-0C4F-5AFB-6FB431E5D39D}.Release|Any CPU.Build.0 = Release|Any CPU - {A7775F69-050F-CC87-3441-23EDC710AFFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7775F69-050F-CC87-3441-23EDC710AFFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A7775F69-050F-CC87-3441-23EDC710AFFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A7775F69-050F-CC87-3441-23EDC710AFFA}.Release|Any CPU.Build.0 = Release|Any CPU - {6800202F-4402-D405-F8CB-03DC7BD78B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6800202F-4402-D405-F8CB-03DC7BD78B92}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6800202F-4402-D405-F8CB-03DC7BD78B92}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6800202F-4402-D405-F8CB-03DC7BD78B92}.Release|Any CPU.Build.0 = Release|Any CPU + {6208DB9F-F8AC-EBCB-7B18-67F4C4065086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6208DB9F-F8AC-EBCB-7B18-67F4C4065086}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6208DB9F-F8AC-EBCB-7B18-67F4C4065086}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6208DB9F-F8AC-EBCB-7B18-67F4C4065086}.Release|Any CPU.Build.0 = Release|Any CPU + {EDA4797C-B86C-95C4-91A7-0692260042EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDA4797C-B86C-95C4-91A7-0692260042EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDA4797C-B86C-95C4-91A7-0692260042EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDA4797C-B86C-95C4-91A7-0692260042EB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Reference-Architecture/Client/MixedReality-Azure-Unity/ProjectSettings/ProjectVersion.txt b/Reference-Architecture/Client/MixedReality-Azure-Unity/ProjectSettings/ProjectVersion.txt index 22977b3..5d90673 100644 --- a/Reference-Architecture/Client/MixedReality-Azure-Unity/ProjectSettings/ProjectVersion.txt +++ b/Reference-Architecture/Client/MixedReality-Azure-Unity/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 2018.1.0f2 +m_EditorVersion: 2018.2.0x-ImprovedPrefabs