예제 #1
0
        public async Task InitiateBrokerHandShakeAsync()
        {
            using (_logger.LogMethodDuration())
            {
                Bundle handShakeBundleResult = await GetHandShakeBundleResultFromBrokerAsync().ConfigureAwait(false);

                _negotiatedBrokerProtocolKey = GetProtocolKeyFromHandShakeResult(handShakeBundleResult);
            }
        }
예제 #2
0
        public async Task <MsalTokenResponse> AcquireTokenSilentAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenSilentParameters acquireTokenSilentParameters)
        {
            using (_logger.LogMethodDuration())
            {
                // Important: MSAL will have already resolved the authority by now,
                // so we are not expecting "common" or "organizations" but a tenanted authority
                bool isMsa = IsMsaRequest(
                    authenticationRequestParameters.Authority,
                    null,
                    IsMsaPassthrough(authenticationRequestParameters));

                IWamPlugin wamPlugin = isMsa ? _msaPlugin : _aadPlugin;

                WebAccountProvider provider;
                if (isMsa)
                {
                    provider = await _webAccountProviderFactory.GetAccountProviderAsync("consumers").ConfigureAwait(false);
                }
                else
                {
                    provider = await _webAccountProviderFactory.GetAccountProviderAsync(authenticationRequestParameters.Authority.AuthorityInfo.CanonicalAuthority)
                               .ConfigureAwait(false);
                }

                WebAccount webAccount = await FindWamAccountForMsalAccountAsync(
                    provider,
                    wamPlugin,
                    authenticationRequestParameters.Account,
                    null, // ATS requires an account object, login_hint is not supported on its own
                    authenticationRequestParameters.ClientId).ConfigureAwait(false);

                if (webAccount == null)
                {
                    throw new MsalUiRequiredException(
                              MsalError.InteractionRequired,
                              "Could not find a WAM account for the silent request.");
                }

                WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync(
                    provider,
                    authenticationRequestParameters,
                    isForceLoginPrompt : false,
                    isAccountInWam : true,
                    isInteractive : false)
                                                  .ConfigureAwait(false);

                AddCommonParamsToRequest(authenticationRequestParameters, webTokenRequest);

                var wamResult =
                    await _wamProxy.GetTokenSilentlyAsync(webAccount, webTokenRequest).ConfigureAwait(false);

                return(CreateMsalTokenResponse(wamResult, wamPlugin, isInteractive: false));
            }
        }
        public bool IsBrokerInstalledAndInvokable()
        {
            using (_logger.LogMethodDuration())
            {
                bool canInvoke = _brokerHelper.CanSwitchToBroker();
                _logger.Verbose("Can invoke broker? " + canInvoke);

                return(canInvoke);
            }
        }
        public bool IsBrokerInstalledAndInvokable(AuthorityType authorityType)
        {
            using (_logger.LogMethodDuration())
            {
                bool canInvoke = CanSwitchToBroker();
                _logger.Verbose("[Android broker] Can invoke broker? " + canInvoke);

                return(canInvoke);
            }
        }
        private async Task AcquireTokenInteractiveViaBrokerAsync(BrokerRequest brokerRequest)
        {
            using (_logger.LogMethodDuration())
            {
                // onActivityResult will receive the response for this activity.
                // Launching this activity will switch to the broker app.

                _logger.Verbose("[Android broker] Starting Android Broker interactive authentication. ");
                Intent brokerIntent = await GetIntentForInteractiveBrokerRequestAsync(brokerRequest).ConfigureAwait(false);

                if (brokerIntent != null)
                {
                    _brokerHelper.LaunchInteractiveActivity(_parentActivity, brokerIntent);
                }
            }
        }
        //Inorder for broker to use the V2 endpoint during authentication, MSAL must initiate a handshake with broker to specify what endpoint should be used for the request.
        public async Task InitiateBrokerHandshakeAsync(Activity callerActivity)
        {
            using (_logger.LogMethodDuration())
            {
                try
                {
                    Bundle helloRequestBundle = new Bundle();
                    helloRequestBundle.PutString(BrokerConstants.ClientAdvertisedMaximumBPVersionKey, BrokerConstants.BrokerProtocalVersionCode);
                    helloRequestBundle.PutString(BrokerConstants.ClientConfiguredMinimumBPVersionKey, "2.0");
                    helloRequestBundle.PutString(BrokerConstants.BrokerAccountManagerOperationKey, "HELLO");

                    IAccountManagerFuture result = _androidAccountManager.AddAccount(BrokerConstants.BrokerAccountType,
                                                                                     BrokerConstants.AuthtokenType,
                                                                                     null,
                                                                                     helloRequestBundle,
                                                                                     null,
                                                                                     null,
                                                                                     GetPreferredLooper(callerActivity));

                    if (result != null)
                    {
                        Bundle bundleResult = (Bundle)await result.GetResultAsync(
                            AccountManagerTimeoutSeconds,
                            TimeUnit.Seconds)
                                              .ConfigureAwait(false);

                        var bpKey = bundleResult?.GetString(BrokerConstants.NegotiatedBPVersionKey);

                        if (!string.IsNullOrEmpty(bpKey))
                        {
                            _logger.Info("Using broker protocol version: " + bpKey);
                            return;
                        }

                        throw new MsalClientException("Could not negotiate protocol version with broker.");
                    }

                    throw new MsalClientException("Could not communicate with broker via account manager");
                }
                catch
                {
                    _logger.Error("Error when trying to initiate communication with the broker.");
                    throw;
                }
            }
        }
예제 #7
0
        public bool IsBrokerInstalledAndInvokable()
        {
            using (_logger.LogMethodDuration())
            {
                if (_uIParent?.CallerViewController == null)
                {
                    _logger.Error(iOSBrokerConstants.CallerViewControllerIsNullCannotInvokeBroker);
                    throw new MsalClientException(MsalError.UIViewControllerRequiredForiOSBroker, MsalErrorMessage.UIViewControllerIsRequiredToInvokeiOSBroker);
                }

                bool canStartBroker = false;

                _uIParent.CallerViewController.InvokeOnMainThread(() =>
                {
                    if (IsBrokerInstalled(BrokerParameter.UriSchemeBrokerV3))
                    {
                        _logger.Info(iOSBrokerConstants.iOSBrokerv3Installed);
                        _brokerV3Installed = true;
                        canStartBroker     = true;
                    }
                });

                if (!canStartBroker)
                {
                    _uIParent.CallerViewController.InvokeOnMainThread(() =>
                    {
                        if (IsBrokerInstalled(BrokerParameter.UriSchemeBrokerV2))
                        {
                            _logger.Info(iOSBrokerConstants.iOSBrokerv2Installed);
                            canStartBroker = true;
                        }
                    });
                }

                if (!canStartBroker)
                {
                    _logger.Info(iOSBrokerConstants.CanInvokeBrokerReturnsFalseMessage);
                }

                return(canStartBroker);
            }
        }
예제 #8
0
        public void AddConfidentialClientParameters(
            OAuth2Client oAuth2Client,
            ICoreLogger logger,
            ICryptographyManager cryptographyManager,
            string clientId,
            Authority authority,
            bool sendX5C)
        {
            using (logger.LogMethodDuration())
            {
                switch (AuthenticationType)
                {
                case ConfidentialClientAuthenticationType.ClientCertificate:
                    string tokenEndpoint = authority.GetTokenEndpoint();

                    var jwtToken2 = new JsonWebToken(
                        cryptographyManager,
                        clientId,
                        tokenEndpoint);

                    string assertion2 = jwtToken2.Sign(this, sendX5C);

                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, assertion2);

                    break;

                case ConfidentialClientAuthenticationType.ClientCertificateWithClaims:
                    tokenEndpoint = authority.GetTokenEndpoint();

                    var jwtToken = new JsonWebToken(
                        cryptographyManager,
                        clientId,
                        tokenEndpoint,
                        ClaimsToSign,
                        AppendDefaultClaims);
                    string assertion = jwtToken.Sign(this, sendX5C);

                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, assertion);

                    break;

                case ConfidentialClientAuthenticationType.ClientSecret:
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientSecret, Secret);
                    break;

                case ConfidentialClientAuthenticationType.SignedClientAssertion:
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, SignedAssertion);
                    break;

                case ConfidentialClientAuthenticationType.SignedClientAssertionDelegate:
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
                    oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, SignedAssertionDelegate.Invoke());
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
예제 #9
0
        //Inorder for broker to use the V2 endpoint during authentication, MSAL must initiate a handshake with broker to specify what endpoint should be used for the request.
        public async Task InitiateBrokerHandshakeAsync(Activity callerActivity)
        {
            using (_logger.LogMethodDuration())
            {
                try
                {
                    Bundle helloRequestBundle = new Bundle();
                    helloRequestBundle.PutString(BrokerConstants.ClientAdvertisedMaximumBPVersionKey, BrokerConstants.BrokerProtocalVersionCode);
                    helloRequestBundle.PutString(BrokerConstants.ClientConfiguredMinimumBPVersionKey, "2.0");
                    helloRequestBundle.PutString(BrokerConstants.BrokerAccountManagerOperationKey, "HELLO");

                    IAccountManagerFuture result = _androidAccountManager.AddAccount(BrokerConstants.BrokerAccountType,
                                                                                     BrokerConstants.AuthtokenType,
                                                                                     null,
                                                                                     helloRequestBundle,
                                                                                     null,
                                                                                     null,
                                                                                     GetPreferredLooper(callerActivity));

                    if (result != null)
                    {
                        Bundle bundleResult = (Bundle)await result.GetResultAsync(
                            AccountManagerTimeoutSeconds,
                            TimeUnit.Seconds)
                                              .ConfigureAwait(false);

                        var bpKey = bundleResult?.GetString(BrokerConstants.NegotiatedBPVersionKey);

                        if (!string.IsNullOrEmpty(bpKey))
                        {
                            _logger.Info("Using broker protocol version: " + bpKey);
                            return;
                        }

                        dynamic errorResult      = JObject.Parse(bundleResult?.GetString(BrokerConstants.BrokerResultV2));
                        string  errorCode        = null;
                        string  errorDescription = null;

                        if (!string.IsNullOrEmpty(errorResult))
                        {
                            errorCode = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString();
                            string errorMessage = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString();
                            errorDescription = $"An error occurred during hand shake with the broker. Error: {errorCode} Error Message: {errorMessage}";
                        }
                        else
                        {
                            errorCode        = BrokerConstants.BrokerUnknownErrorCode;
                            errorDescription = "An error occurred during hand shake with the broker, no detailed error information was returned";
                        }

                        _logger.Error(errorDescription);
                        throw new MsalClientException(errorCode, errorDescription);
                    }

                    throw new MsalClientException("Could not communicate with broker via account manager");
                }
                catch
                {
                    _logger.Error("Error when trying to initiate communication with the broker.");
                    throw;
                }
            }
        }
예제 #10
0
        public async Task <MsalTokenResponse> AcquireTokenSilentAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenSilentParameters acquireTokenSilentParameters)
        {
            using (_logger.LogMethodDuration())
            {
                // Important: MSAL will have already resolved the authority by now,
                // so we are not expecting "common" or "organizations" but a tenanted authority
                bool isMsa = await IsMsaRequestAsync(
                    authenticationRequestParameters.Authority,
                    null,
                    _wamOptions.MsaPassthrough)
                             .ConfigureAwait(false);

                IWamPlugin wamPlugin = isMsa ? _msaPlugin : _aadPlugin;

                WebAccountProvider provider;
                if (_wamOptions.MsaPassthrough)
                {
                    provider = await GetProviderAsync(
                        "organizations", false).ConfigureAwait(false);
                }
                else
                {
                    provider = await GetProviderAsync(
                        authenticationRequestParameters.AuthorityInfo.CanonicalAuthority,
                        isMsa).ConfigureAwait(false);
                }

                WebAccount webAccount = await FindWamAccountForMsalAccountAsync(
                    provider,
                    wamPlugin,
                    authenticationRequestParameters.Account,
                    null, // ATS requires an account object, login_hint is not supported on its own
                    authenticationRequestParameters.AppConfig.ClientId).ConfigureAwait(false);

                if (webAccount == null && _wamOptions.MsaPassthrough)
                {
                    return(await AcquireMsaTokenSilentForPassthroughAsync(
                               authenticationRequestParameters,
                               provider).ConfigureAwait(false));
                }

                if (webAccount == null)
                {
                    throw new MsalUiRequiredException(
                              MsalError.InteractionRequired,
                              "Could not find a WAM account for the silent request.");
                }

                WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync(
                    provider,
                    authenticationRequestParameters,
                    isForceLoginPrompt : false,
                    isAccountInWam : true,
                    isInteractive : false)
                                                  .ConfigureAwait(false);

                // For MSA-PT scenario, MSAL's authority is wrong. MSAL will use Account.HomeTenantId
                // which will essentialyl be /consumers. This is wrong, we are not trying to obtain
                // an MSA token, we are trying to obtain an ADD *guest* token.
                string differentAuthority = null;
                if (_wamOptions.MsaPassthrough &&
                    authenticationRequestParameters.Authority is AadAuthority aadAuthority &&
                    aadAuthority.IsConsumers())
                {
                    differentAuthority = authenticationRequestParameters.Authority.GetTenantedAuthority("organizations", forceTenantless: true);
                }

                WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequest, _logger, differentAuthority);

                var wamResult =
                    await _wamProxy.GetTokenSilentlyAsync(webAccount, webTokenRequest).ConfigureAwait(false);

                return(WamAdapters.CreateMsalResponseFromWamResponse(
                           wamResult,
                           wamPlugin,
                           authenticationRequestParameters.AppConfig.ClientId,
                           _logger,
                           isInteractive: false));
            }
        }
예제 #11
0
        public static Dictionary <string, string> CreateClientCredentialBodyParameters(
            ICoreLogger logger,
            ICryptographyManager cryptographyManager,
            ClientCredentialWrapper clientCredential,
            string clientId,
            AuthorityEndpoints endpoints,
            bool sendX5C)
        {
            using (logger.LogMethodDuration())
            {
                Dictionary <string, string> parameters = new Dictionary <string, string>();
                if (clientCredential != null)
                {
                    if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.ClientSecret)
                    {
                        parameters[OAuth2Parameter.ClientSecret] = clientCredential.Secret;
                    }
                    else
                    {
                        if ((clientCredential.CachedAssertion == null || clientCredential.ValidTo != 0) &&
                            clientCredential.AuthenticationType != ConfidentialClientAuthenticationType.SignedClientAssertion &&
                            clientCredential.AuthenticationType != ConfidentialClientAuthenticationType.SignedClientAssertionDelegate)
                        {
                            if (!ValidateClientAssertion(clientCredential, endpoints.SelfSignedJwtAudience, sendX5C))
                            {
                                logger.Info(LogMessages.ClientAssertionDoesNotExistOrNearExpiry);

                                JsonWebToken jwtToken;

                                if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.ClientCertificateWithClaims)
                                {
                                    jwtToken = new JsonWebToken(cryptographyManager, clientId, endpoints.SelfSignedJwtAudience, clientCredential.ClaimsToSign, clientCredential.AppendDefaultClaims);
                                }
                                else
                                {
                                    jwtToken = new JsonWebToken(cryptographyManager, clientId, endpoints.SelfSignedJwtAudience);
                                }

                                clientCredential.CachedAssertion = jwtToken.Sign(clientCredential, sendX5C);
                                clientCredential.ValidTo         = jwtToken.ValidTo;
                                clientCredential.ContainsX5C     = sendX5C;
                                clientCredential.Audience        = endpoints.SelfSignedJwtAudience;
                            }
                            else
                            {
                                logger.Info(LogMessages.ReusingTheUnexpiredClientAssertion);
                            }
                        }

                        parameters[OAuth2Parameter.ClientAssertionType] = OAuth2AssertionType.JwtBearer;

                        if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.SignedClientAssertion)
                        {
                            parameters[OAuth2Parameter.ClientAssertion] = clientCredential.SignedAssertion;
                        }
                        else if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.SignedClientAssertionDelegate)
                        {
                            parameters[OAuth2Parameter.ClientAssertion] = clientCredential.SignedAssertionDelegate();
                        }
                        else
                        {
                            parameters[OAuth2Parameter.ClientAssertion] = clientCredential.CachedAssertion;
                        }
                    }
                }
                return(parameters);
            }
        }