예제 #1
0
        private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult)
        {
            AuthorizationResult result;

            switch (webAuthenticationResult.ResponseStatus)
            {
            case WebAuthenticationStatus.Success:
                result = AuthorizationResult.FromUri(webAuthenticationResult.ResponseData);
                break;

            case WebAuthenticationStatus.ErrorHttp:
                result      = AuthorizationResult.FromStatus(AuthorizationStatus.ErrorHttp);
                result.Code = webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.InvariantCulture);
                break;

            case WebAuthenticationStatus.UserCancel:
                result = AuthorizationResult.FromStatus(AuthorizationStatus.UserCancel);
                break;

            default:
                result = AuthorizationResult.FromStatus(
                    AuthorizationStatus.UnknownError,
                    MsalError.WABError,
                    MsalErrorMessage.WABError(
                        webAuthenticationResult.ResponseStatus.ToString(),
                        webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.InvariantCulture),
                        webAuthenticationResult.ResponseData));
                break;
            }

            return(result);
        }
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(
            Uri authorizationUri,
            Uri redirectUri,
            RequestContext requestContext,
            CancellationToken cancellationToken)
        {
            var authCodeUri = await InterceptAuthorizationUriAsync(
                authorizationUri,
                redirectUri,
                cancellationToken)
                              .ConfigureAwait(true);


            if (!authCodeUri.Authority.Equals(redirectUri.Authority, StringComparison.OrdinalIgnoreCase) ||
                !authCodeUri.AbsolutePath.Equals(redirectUri.AbsolutePath))
            {
                throw new MsalClientException(
                          MsalError.LoopbackResponseUriMisatch,
                          MsalErrorMessage.RedirectUriMismatch(
                              authCodeUri.AbsolutePath,
                              redirectUri.AbsolutePath));
            }

            return(AuthorizationResult.FromUri(authCodeUri.OriginalString));
        }
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(
            Uri authorizationUri,
            Uri redirectUri,
            RequestContext requestContext,
            CancellationToken cancellationToken)
        {
            try
            {
                var authCodeUri = await InterceptAuthorizationUriAsync(
                    authorizationUri,
                    redirectUri,
                    cancellationToken)
                                  .ConfigureAwait(true);

                if (!authCodeUri.Authority.Equals(redirectUri.Authority, StringComparison.OrdinalIgnoreCase) ||
                    !authCodeUri.AbsolutePath.Equals(redirectUri.AbsolutePath))
                {
                    throw new MsalClientException(
                              MsalError.LoopbackResponseUriMismatch,
                              MsalErrorMessage.RedirectUriMismatch(
                                  authCodeUri.AbsolutePath,
                                  redirectUri.AbsolutePath));
                }

                return(AuthorizationResult.FromUri(authCodeUri.OriginalString));
            }
            catch (System.Net.HttpListenerException) // sometimes this exception sneaks out (see issue 1773)
            {
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        public async Task <MsalTokenResponse> SendTokenRequestAsync(
            IDictionary <string, string> additionalBodyParameters,
            string scopeOverride                = null,
            string tokenEndpointOverride        = null,
            CancellationToken cancellationToken = default)
        {
            using (_requestParams.RequestContext.Logger.LogMethodDuration())
            {
                cancellationToken.ThrowIfCancellationRequested();

                string tokenEndpoint = tokenEndpointOverride ?? _requestParams.Endpoints.TokenEndpoint;
                string scopes        = !string.IsNullOrEmpty(scopeOverride) ? scopeOverride : GetDefaultScopes(_requestParams.Scope);

                AddBodyParamsAndHeaders(additionalBodyParameters, scopes);
                AddThrottlingHeader();

                _serviceBundle.ThrottlingManager.TryThrottle(_requestParams, _oAuth2Client.GetBodyParameters());

                MsalTokenResponse response;
                try
                {
                    response = await SendHttpAndClearTelemetryAsync(tokenEndpoint, _requestParams.RequestContext.Logger)
                               .ConfigureAwait(false);
                }
                catch (MsalServiceException e)
                {
                    _serviceBundle.ThrottlingManager.RecordException(_requestParams, _oAuth2Client.GetBodyParameters(), e);
                    throw;
                }

                if (string.IsNullOrEmpty(response.Scope))
                {
                    response.Scope = _requestParams.Scope.AsSingleString();
                    _requestParams.RequestContext.Logger.Info(
                        "ScopeSet was missing from the token response, so using developer provided scopes in the result. ");
                }

                if (string.IsNullOrEmpty(response.TokenType))
                {
                    throw new MsalClientException(MsalError.AccessTokenTypeMissing, MsalErrorMessage.AccessTokenTypeMissing);
                }

                if (!string.Equals(
                        response.TokenType,
                        _requestParams.AuthenticationScheme.AccessTokenType,
                        StringComparison.OrdinalIgnoreCase))
                {
                    throw new MsalClientException(
                              MsalError.TokenTypeMismatch,
                              MsalErrorMessage.TokenTypeMismatch(
                                  _requestParams.AuthenticationScheme.AccessTokenType,
                                  response.TokenType));
                }

                return(response);
            }
        }
        private static byte[] CreateAndStoreBrokerKey(ICoreLogger logger)
        {
            logger.Info("CreateAndStoreBrokerKey - creating a new key");

            byte[] brokerKey;
            byte[] rawBytes;
            using (AesManaged algo = CreateSymmetricAlgorith(null))
            {
                algo.GenerateKey();
                rawBytes = algo.Key;
            }

            NSData byteData = NSData.FromArray(rawBytes);

            var recordToAdd = new SecRecord(SecKind.GenericPassword)
            {
                Generic     = NSData.FromString(iOSBrokerConstants.LocalSettingsContainerName),
                Service     = iOSBrokerConstants.BrokerKeyService,
                Account     = iOSBrokerConstants.BrokerKeyAccount,
                Label       = iOSBrokerConstants.BrokerKeyLabel,
                Comment     = iOSBrokerConstants.BrokerKeyComment,
                Description = iOSBrokerConstants.BrokerKeyStorageDescription,
                ValueData   = byteData
            };

            var result = SecKeyChain.Add(recordToAdd);

            if (result == SecStatusCode.DuplicateItem)
            {
                logger.Info("Could not add the broker key, a key already exists. Trying to delete it first.");
                var recordToRemove = new SecRecord(SecKind.GenericPassword)
                {
                    Service = iOSBrokerConstants.BrokerKeyService,
                    Account = iOSBrokerConstants.BrokerKeyAccount,
                };

                var removeResult = SecKeyChain.Remove(recordToRemove);
                logger.Info("Broker key removal result: " + removeResult);

                result = SecKeyChain.Add(recordToAdd);
                logger.Info("Broker key re-adding result: " + result);
            }

            if (result != SecStatusCode.Success)
            {
                logger.Error("Failed to save the broker key to keychain. Result " + result);
                throw new MsalClientException(
                          MsalError.BrokerKeySaveFailed,
                          MsalErrorMessage.iOSBrokerKeySaveFailed(result.ToString()));
            }

            brokerKey = byteData.ToArray();
            return(brokerKey);
        }
        /// <inheritdoc />
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(
            Uri authorizationUri,
            Uri redirectUri,
            RequestContext requestContext,
            CancellationToken cancellationToken)
        {
            requestContext.Logger.Info(LogMessages.CustomWebUiAcquiringAuthorizationCode);

            try
            {
                requestContext.Logger.InfoPii(LogMessages.CustomWebUiCallingAcquireAuthorizationCodePii(authorizationUri, redirectUri),
                                              LogMessages.CustomWebUiCallingAcquireAuthorizationCodeNoPii);
                var uri = await _customWebUi.AcquireAuthorizationCodeAsync(authorizationUri, redirectUri, cancellationToken)
                          .ConfigureAwait(false);

                if (uri == null || String.IsNullOrWhiteSpace(uri.Query))
                {
                    throw new MsalClientException(
                              MsalError.CustomWebUiReturnedInvalidUri,
                              MsalErrorMessage.CustomWebUiReturnedInvalidUri);
                }

                if (uri.Authority.Equals(redirectUri.Authority, StringComparison.OrdinalIgnoreCase) &&
                    uri.AbsolutePath.Equals(redirectUri.AbsolutePath))
                {
                    IDictionary <string, string> inputQp = CoreHelpers.ParseKeyValueList(
                        authorizationUri.Query.Substring(1),
                        '&',
                        true,
                        null);

                    requestContext.Logger.Info(LogMessages.CustomWebUiRedirectUriMatched);
                    return(new AuthorizationResult(AuthorizationStatus.Success, uri.OriginalString));
                }

                throw new MsalClientException(
                          MsalError.CustomWebUiRedirectUriMismatch,
                          MsalErrorMessage.CustomWebUiRedirectUriMismatch(
                              uri.AbsolutePath,
                              redirectUri.AbsolutePath));
            }
            catch (OperationCanceledException)
            {
                requestContext.Logger.Info(LogMessages.CustomWebUiOperationCancelled);
                return(new AuthorizationResult(AuthorizationStatus.UserCancel, null));
            }
            catch (Exception ex)
            {
                requestContext.Logger.WarningPiiWithPrefix(ex, MsalErrorMessage.CustomWebUiAuthorizationCodeFailed);
                throw;
            }
        }
 private static void ValidateTypeMismatch(AuthorityInfo configAuthorityInfo, AuthorityInfo requestAuthorityInfo)
 {
     if (!configAuthorityInfo.IsDefaultAuthority &&
         requestAuthorityInfo != null &&
         configAuthorityInfo.AuthorityType != requestAuthorityInfo.AuthorityType)
     {
         throw new MsalClientException(
                   MsalError.AuthorityTypeMismatch,
                   MsalErrorMessage.AuthorityTypeMismatch(
                       configAuthorityInfo.AuthorityType,
                       requestAuthorityInfo.AuthorityType));
     }
 }
예제 #8
0
        /// <summary>
        /// Enables Windows broker flows on older platforms, such as .NET framework, where these are not available in the box with Microsoft.Identity.Client
        /// For details about Windows broker, see https://aka.ms/msal-net-wam
        /// </summary>
        public static PublicClientApplicationBuilder WithWindowsBroker(this PublicClientApplicationBuilder builder, bool enableBroker = true)
        {
            if (!builder.Config.ExperimentalFeaturesEnabled)
            {
                throw new MsalClientException(
                          MsalError.ExperimentalFeature,
                          MsalErrorMessage.ExperimentalFeature(nameof(WithWindowsBroker)));
            }

            builder.Config.IsBrokerEnabled = enableBroker;
            AddSupportForWam(builder);
            return(builder);
        }
예제 #9
0
        /// <summary>
        /// Declares that the app is MSA-Passthrough enabled (Microsoft internal only). This is a legacy
        /// feature. Required for the functionality of some brokers, like WAM.
        /// </summary>
        public static PublicClientApplicationBuilder WithMsaPassthrough(
            this PublicClientApplicationBuilder builder,
            bool enabled = true)
        {
            if (!builder.Config.ExperimentalFeaturesEnabled)
            {
                throw new MsalClientException(
                          MsalError.ExperimentalFeature,
                          MsalErrorMessage.ExperimentalFeature(nameof(WithMsaPassthrough)));
            }

            builder.Config.IsMsaPassthrough = enabled;
            return(builder);
        }
        /// <summary>
        /// Enables Windows broker flows on older platforms, such as .NET framework, where these are not available in the box with Microsoft.Identity.Client
        /// For details about Windows broker, see https://aka.ms/msal-net-wam
        /// </summary>
        public static PublicClientApplicationBuilder WithWindowsBroker(this PublicClientApplicationBuilder builder, bool enableBroker = true)
        {
            if (!builder.Config.ExperimentalFeaturesEnabled)
            {
                throw new MsalClientException(
                          MsalError.ExperimentalFeature,
                          MsalErrorMessage.ExperimentalFeature(nameof(WithWindowsBroker)));
            }

            builder.Config.IsBrokerEnabled   = true;
            builder.Config.BrokerCreatorFunc =
                (uiParent, logger) => new Platforms.Features.WamBroker.WamBroker(uiParent, logger);
            return(builder);
        }
예제 #11
0
        public InstanceDiscoveryMetadataEntry GetMetadataOrThrow(string environment, ICoreLogger logger)
        {
            _entries.TryGetValue(environment ?? "", out InstanceDiscoveryMetadataEntry entry);

            logger.Verbose($"[Instance Discovery] Tried to use user metadata provider for {environment}. Success? {entry != null}");

            if (entry == null)
            {
                throw new MsalClientException(
                          MsalError.InvalidUserInstanceMetadata,
                          MsalErrorMessage.NoUserInstanceMetadataEntry(environment));
            }

            return(entry);
        }
        public async Task <MsalTokenResponse> SendTokenRequestAsync(
            IDictionary <string, string> additionalBodyParameters,
            string scopeOverride                = null,
            string tokenEndpointOverride        = null,
            CancellationToken cancellationToken = default)
        {
            string tokenEndpoint = tokenEndpointOverride ?? _requestParams.Endpoints.TokenEndpoint;
            string scopes        = !string.IsNullOrEmpty(scopeOverride) ? scopeOverride : GetDefaultScopes(_requestParams.Scope);

            AddBodyParamsAndHeaders(additionalBodyParameters, scopes);

            MsalTokenResponse response = await SendHttpAndClearTelemetryAsync(tokenEndpoint)
                                         .ConfigureAwait(false);


            if (string.IsNullOrEmpty(response.Scope))
            {
                response.Scope = _requestParams.Scope.AsSingleString();
                _requestParams.RequestContext.Logger.Info(
                    "ScopeSet was missing from the token response, so using developer provided scopes in the result. ");
            }

            if (!string.IsNullOrEmpty(response.TokenType) &&
                !string.Equals(
                    response.TokenType,
                    _requestParams.AuthenticationScheme.AccessTokenType,
                    StringComparison.OrdinalIgnoreCase))
            {
                throw new MsalClientException(
                          MsalError.TokenTypeMismatch,
                          MsalErrorMessage.TokenTypeMismatch(
                              _requestParams.AuthenticationScheme.AccessTokenType,
                              response.TokenType));
            }

            return(response);
        }
        protected async Task <MsalTokenResponse> SendTokenRequestAsync(
            string tokenEndpoint,
            IDictionary <string, string> additionalBodyParameters,
            CancellationToken cancellationToken)
        {
            OAuth2Client client = new OAuth2Client(ServiceBundle.DefaultLogger, ServiceBundle.HttpManager, ServiceBundle.TelemetryManager);

            client.AddBodyParameter(OAuth2Parameter.ClientId, AuthenticationRequestParameters.ClientId);
            client.AddBodyParameter(OAuth2Parameter.ClientInfo, "1");


#if DESKTOP || NETSTANDARD1_3 || NET_CORE
            if (AuthenticationRequestParameters.ClientCredential != null)
            {
                Dictionary <string, string> ccBodyParameters = ClientCredentialHelper.CreateClientCredentialBodyParameters(
                    AuthenticationRequestParameters.RequestContext.Logger,
                    ServiceBundle.PlatformProxy.CryptographyManager,
                    AuthenticationRequestParameters.ClientCredential,
                    AuthenticationRequestParameters.ClientId,
                    AuthenticationRequestParameters.Endpoints,
                    AuthenticationRequestParameters.SendX5C);

                foreach (var entry in ccBodyParameters)
                {
                    client.AddBodyParameter(entry.Key, entry.Value);
                }
            }
#endif

            client.AddBodyParameter(OAuth2Parameter.Scope,
                                    GetDecoratedScope(AuthenticationRequestParameters.Scope).AsSingleString());

            client.AddQueryParameter(OAuth2Parameter.Claims, AuthenticationRequestParameters.Claims);

            foreach (var kvp in additionalBodyParameters)
            {
                client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            foreach (var kvp in AuthenticationRequestParameters.AuthenticationScheme.GetTokenRequestParams())
            {
                client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            MsalTokenResponse response = await SendHttpMessageAsync(client, tokenEndpoint)
                                         .ConfigureAwait(false);

            if (!string.Equals(
                    response.TokenType,
                    AuthenticationRequestParameters.AuthenticationScheme.AccessTokenType,
                    StringComparison.OrdinalIgnoreCase))
            {
                throw new MsalClientException(
                          MsalError.TokenTypeMismatch,
                          MsalErrorMessage.TokenTypeMismatch(
                              AuthenticationRequestParameters.AuthenticationScheme.AccessTokenType,
                              response.TokenType));
            }

            return(response);
        }
 private static void HandleInvalidExternalValueError(string nameOfValue)
 {
     throw new MsalClientException(MsalError.InvalidTokenProviderResponseValue, MsalErrorMessage.InvalidTokenProviderResponseValue(nameOfValue));
 }
        /// <summary>
        /// Registers security and sets the security values for the process.
        /// </summary>
        /// <remarks>
        /// Workaround to enable WAM Account Picker in an elevated process.
        /// </remarks>
        public static void InitializeProcessSecurity()
        {
            int result = CoInitializeSecurity(
                IntPtr.Zero, -1, IntPtr.Zero,
                IntPtr.Zero, RpcAuthnLevel.None,
                RpcImpLevel.Impersonate, IntPtr.Zero,
                EoAuthnCap.None, IntPtr.Zero);

            if (result != 0)
            {
                throw new MsalClientException(MsalError.InitializeProcessSecurityError, MsalErrorMessage.InitializeProcessSecurityError($"0x{result:x}"));
            }
        }
        public async Task <MsalTokenResponse> SendTokenRequestAsync(
            IDictionary <string, string> additionalBodyParameters,
            string scopeOverride                = null,
            string tokenEndpointOverride        = null,
            CancellationToken cancellationToken = default)
        {
            string tokenEndpoint = tokenEndpointOverride ?? _requestParams.Endpoints.TokenEndpoint;
            string scopes        = !string.IsNullOrEmpty(scopeOverride) ? scopeOverride: GetDefaultScopes(_requestParams.Scope);

            _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientId, _requestParams.ClientId);
            _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientInfo, "1");


#if DESKTOP || NETSTANDARD1_3 || NET_CORE
            if (_requestParams.ClientCredential != null)
            {
                Dictionary <string, string> ccBodyParameters = ClientCredentialHelper.CreateClientCredentialBodyParameters(
                    _requestParams.RequestContext.Logger,
                    _serviceBundle.PlatformProxy.CryptographyManager,
                    _requestParams.ClientCredential,
                    _requestParams.ClientId,
                    _requestParams.Endpoints,
                    _requestParams.SendX5C);

                foreach (var entry in ccBodyParameters)
                {
                    _oAuth2Client.AddBodyParameter(entry.Key, entry.Value);
                }
            }
#endif

            _oAuth2Client.AddBodyParameter(OAuth2Parameter.Scope, scopes);
            _oAuth2Client.AddBodyParameter(OAuth2Parameter.Claims, _requestParams.ClaimsAndClientCapabilities);

            foreach (var kvp in additionalBodyParameters)
            {
                _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            foreach (var kvp in _requestParams.AuthenticationScheme.GetTokenRequestParams())
            {
                _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value);
            }

            MsalTokenResponse response = await SendHttpMessageAsync(tokenEndpoint)
                                         .ConfigureAwait(false);

            if (!string.Equals(
                    response.TokenType,
                    _requestParams.AuthenticationScheme.AccessTokenType,
                    StringComparison.OrdinalIgnoreCase))
            {
                throw new MsalClientException(
                          MsalError.TokenTypeMismatch,
                          MsalErrorMessage.TokenTypeMismatch(
                              _requestParams.AuthenticationScheme.AccessTokenType,
                              response.TokenType));
            }

            return(response);
        }