コード例 #1
0
        /// <summary>
        /// Check common redirect uri problems.
        /// Optionally check that the redirect uri is not the OAuth2 standard redirect uri urn:ietf:wg:oauth:2.0:oob
        /// when using a system browser, because the browser cannot redirect back to the app.
        /// </summary>
        public static void Validate(Uri redirectUri, bool usesSystemBrowser = false)
        {
            if (redirectUri == null)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.NoRedirectUri,
                          CoreErrorMessages.NoRedirectUri);
            }

            if (!string.IsNullOrWhiteSpace(redirectUri.Fragment))
            {
                throw new ArgumentException(
                          CoreErrorMessages.RedirectUriContainsFragment,
                          nameof(redirectUri));
            }

            // Currently only MSAL supports the system browser, on Android and iOS
            if (usesSystemBrowser &&
                Constants.DefaultRedirectUri.Equals(redirectUri.AbsoluteUri, StringComparison.OrdinalIgnoreCase))
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.DefaultRedirectUriIsInvalid,
                          string.Format(
                              CultureInfo.InvariantCulture,
                              CoreErrorMessages.DefaultRedirectUriIsInvalid,
                              Constants.DefaultRedirectUri));
            }
        }
コード例 #2
0
        public void Authenticate(Uri authorizationUri, Uri redirectUri, RequestContext requestContext)
        {
            UIViewController viewController = null;

            InvokeOnMainThread(() =>
            {
                UIWindow window = UIApplication.SharedApplication.KeyWindow;
                viewController  = CoreUIParent.FindCurrentViewController(window.RootViewController);
            });
            try
            {
                viewController.InvokeOnMainThread(() =>
                {
                    var navigationController =
                        new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri,
                                                                      redirectUri.OriginalString, CallbackMethod, CoreUIParent.PreferredStatusBarStyle)
                    {
                        ModalPresentationStyle = CoreUIParent.ModalPresentationStyle,
                        ModalTransitionStyle   = CoreUIParent.ModalTransitionStyle,
                        TransitioningDelegate  = viewController.TransitioningDelegate
                    };

                    viewController.PresentViewController(navigationController, true, null);
                });
            }
            catch (Exception ex)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.AuthenticationUiFailed,
                          "See inner exception for details",
                          ex);
            }
        }
コード例 #3
0
        public void MsalServiceException_FromHttpResponse()
        {
            // Arrange
            string responseBody   = "body";
            var    statusCode     = HttpStatusCode.BadRequest;
            var    retryAfterSpan = new TimeSpan(3600);

            var httpResponse = new HttpResponseMessage(statusCode)
            {
                Content = new StringContent(responseBody)
            };

            httpResponse.Headers.RetryAfter = new RetryConditionHeaderValue(retryAfterSpan);
            var coreResponse = HttpManager.CreateResponseAsync(httpResponse).Result;

            // Act
            var msalException = MsalExceptionFactory.GetServiceException(ExCode, ExMessage, coreResponse);

            // Assert
            var msalServiceException = msalException as MsalServiceException;

            Assert.AreEqual(ExCode, msalServiceException.ErrorCode);
            Assert.AreEqual(responseBody, msalServiceException.ResponseBody);
            Assert.AreEqual(ExMessage, msalServiceException.Message);
            Assert.AreEqual((int)statusCode, msalServiceException.StatusCode);

            Assert.AreEqual(retryAfterSpan, msalServiceException.Headers.RetryAfter.Delta);
        }
        public async override Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext)
        {
            returnedUriReady = new SemaphoreSlim(0);

            try
            {
                var agentIntent = new Intent(_parent.Activity, typeof(AuthenticationActivity));
                agentIntent.PutExtra(AndroidConstants.RequestUrlKey, authorizationUri.AbsoluteUri);
                agentIntent.PutExtra(AndroidConstants.CustomTabRedirect, redirectUri.OriginalString);
                AuthenticationActivity.RequestContext = RequestContext;
                _parent.Activity.RunOnUiThread(() => _parent.Activity.StartActivityForResult(agentIntent, 0));
            }
            catch (Exception ex)
            {
                requestContext.Logger.ErrorPii(ex);
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.AuthenticationUiFailedError,
                          "AuthenticationActivity failed to start",
                          ex);
            }

            await returnedUriReady.WaitAsync().ConfigureAwait(false);

            return(authorizationResult);
        }
        private string GetTeamId()
        {
            var queryRecord = new SecRecord(SecKind.GenericPassword)
            {
                Service    = "",
                Account    = TeamIdKey,
                Accessible = SecAccessible.Always
            };

            SecRecord match = SecKeyChain.QueryAsRecord(queryRecord, out SecStatusCode resultCode);

            if (resultCode == SecStatusCode.ItemNotFound)
            {
                SecKeyChain.Add(queryRecord);
                match = SecKeyChain.QueryAsRecord(queryRecord, out resultCode);
            }

            if (resultCode == SecStatusCode.Success)
            {
                return(match.AccessGroup.Split('.')[0]);
            }

            throw MsalExceptionFactory.GetClientException(
                      CoreErrorCodes.CannotAccessPublisherKeyChain,
                      CoreErrorMessages.CannotAccessPublisherKeyChain);
        }
コード例 #6
0
        public void MsalUiRequiredException()
        {
            // Arrange
            string innerExMsg     = "innerExMsg";
            var    innerException = new NotImplementedException(innerExMsg);

            // Act
            var msalException = MsalExceptionFactory.GetUiRequiredException(ExCode, ExMessage, innerException, null);

            // Assert
            var msalServiceException = msalException as MsalUiRequiredException;

            Assert.AreEqual(innerException, msalServiceException.InnerException);
            Assert.AreEqual(ExCode, msalServiceException.ErrorCode);
            Assert.IsNull(msalServiceException.Claims);
            Assert.IsNull(msalServiceException.ResponseBody);
            Assert.AreEqual(ExMessage, msalServiceException.Message);
            Assert.AreEqual(0, msalServiceException.StatusCode);

            // Act
            string piiMessage = MsalExceptionFactory.GetPiiScrubbedDetails(msalException);

            // Assert
            Assert.IsFalse(string.IsNullOrEmpty(piiMessage));
            Assert.IsTrue(
                piiMessage.Contains(typeof(MsalUiRequiredException).Name),
                "The pii message should contain the exception type");
            Assert.IsTrue(
                piiMessage.Contains(typeof(NotImplementedException).Name),
                "The pii message should have the inner exception type");
            Assert.IsTrue(piiMessage.Contains(ExCode));
            Assert.IsFalse(piiMessage.Contains(ExMessage));
            Assert.IsFalse(piiMessage.Contains(innerExMsg));
        }
        /// <inheritdoc/>
        public async Task <MexDocument> GetMexDocumentAsync(string federationMetadataUrl, RequestContext requestContext)
        {
            var          uri          = new UriBuilder(federationMetadataUrl);
            HttpResponse httpResponse = await _httpManager.SendGetAsync(uri.Uri, null, requestContext).ConfigureAwait(false);

            if (httpResponse.StatusCode != System.Net.HttpStatusCode.OK)
            {
                throw MsalExceptionFactory.GetServiceException(
                          CoreErrorCodes.AccessingWsMetadataExchangeFailed,
                          string.Format(CultureInfo.CurrentCulture,
                                        CoreErrorMessages.HttpRequestUnsuccessful,
                                        (int)httpResponse.StatusCode, httpResponse.StatusCode),
                          new ExceptionDetail()
                {
                    StatusCode        = (int)httpResponse.StatusCode,
                    ServiceErrorCodes = new[] { httpResponse.StatusCode.ToString() }
                });
            }

            var mexDoc = new MexDocument(httpResponse.Body);

            requestContext.Logger.InfoPii(
                $"MEX document fetched and parsed from '{federationMetadataUrl}'",
                "Fetched and parsed MEX");

            return(mexDoc);
        }
コード例 #8
0
        /// <summary>
        /// Get the user logged in to Windows or throws
        /// </summary>
        /// <returns>Upn or throws</returns>
        public async Task <string> GetUserPrincipalNameAsync()
        {
            // TODO: there is discrepancy between the implementation of this method on net45 - throws if upn not found - and uap and
            // the rest of the platforms - returns ""

            return(await Task.Factory.StartNew(() =>
            {
                const int NameUserPrincipal = 8;
                uint userNameSize = 0;
                WindowsNativeMethods.GetUserNameEx(NameUserPrincipal, null, ref userNameSize);
                if (userNameSize == 0)
                {
                    throw MsalExceptionFactory.GetClientException(
                        CoreErrorCodes.GetUserNameFailed,
                        CoreErrorMessages.GetUserNameFailed,
                        new Win32Exception(Marshal.GetLastWin32Error()));
                }

                StringBuilder sb = new StringBuilder((int)userNameSize);
                if (!WindowsNativeMethods.GetUserNameEx(NameUserPrincipal, sb, ref userNameSize))
                {
                    throw MsalExceptionFactory.GetClientException(
                        CoreErrorCodes.GetUserNameFailed,
                        CoreErrorMessages.GetUserNameFailed,
                        new Win32Exception(Marshal.GetLastWin32Error()));
                }

                return sb.ToString();
            }).ConfigureAwait(false));
        }
        internal async Task <WsTrustResponse> GetWsTrustResponseAsync(
            UserAuthType userAuthType,
            string cloudAudienceUrn,
            WsTrustEndpoint endpoint,
            IUsernameInput usernameInput)
        {
            // TODO: need to clean up the casting to UsernamePasswordInput as well as removing the PasswordToCharArray
            // since we're putting the strings onto the managed heap anyway.
            string wsTrustRequestMessage = userAuthType == UserAuthType.IntegratedAuth
                ? endpoint.BuildTokenRequestMessageWindowsIntegratedAuth(cloudAudienceUrn)
                : endpoint.BuildTokenRequestMessageUsernamePassword(
                cloudAudienceUrn,
                usernameInput.UserName,
                new string(((UsernamePasswordInput)usernameInput).PasswordToCharArray()));

            try
            {
                WsTrustResponse wsTrustResponse = await _serviceBundle.WsTrustWebRequestManager.GetWsTrustResponseAsync(
                    endpoint, wsTrustRequestMessage, _requestContext).ConfigureAwait(false);

                _requestContext.Logger.Info($"Token of type '{wsTrustResponse.TokenType}' acquired from WS-Trust endpoint");
                return(wsTrustResponse);
            }
            catch (Exception ex)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.ParsingWsTrustResponseFailed,
                          ex.Message,
                          ex);
            }
        }
コード例 #10
0
        protected override async Task <string> GetOpenIdConfigurationEndpointAsync(
            string userPrincipalName,
            RequestContext requestContext)
        {
            if (ValidateAuthority)
            {
                var drsResponse = await GetMetadataFromEnrollmentServerAsync(
                    userPrincipalName,
                    requestContext)
                                  .ConfigureAwait(false);

                if (!string.IsNullOrEmpty(drsResponse.Error))
                {
                    MsalExceptionFactory.GetServiceException(
                        drsResponse.Error,
                        drsResponse.ErrorDescription,
                        ExceptionDetail.FromDrsResponse(drsResponse));
                }

                if (drsResponse.IdentityProviderService?.PassiveAuthEndpoint == null)
                {
                    throw MsalExceptionFactory.GetServiceException(
                              CoreErrorCodes.MissingPassiveAuthEndpoint,
                              CoreErrorMessages.CannotFindTheAuthEndpont,
                              ExceptionDetail.FromDrsResponse(drsResponse));
                }

                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);

                var httpResponse =
                    await ServiceBundle.HttpManager.SendGetAsync(new Uri(webfingerUrl), null, requestContext).ConfigureAwait(false);

                if (httpResponse.StatusCode != HttpStatusCode.OK)
                {
                    throw MsalExceptionFactory.GetServiceException(
                              CoreErrorCodes.InvalidAuthority,
                              CoreErrorMessages.AuthorityValidationFailed,
                              httpResponse);
                }

                var wfr = OAuth2Client.CreateResponse <AdfsWebFingerResponse>(httpResponse, requestContext, false);
                if (wfr.Links.FirstOrDefault(
                        a => a.Rel.Equals(DefaultRealm, StringComparison.OrdinalIgnoreCase) &&
                        a.Href.Equals(resource, StringComparison.OrdinalIgnoreCase)) == null)
                {
                    throw MsalExceptionFactory.GetClientException(
                              CoreErrorCodes.InvalidAuthority,
                              CoreErrorMessages.InvalidAuthorityOpenId);
                }
            }

            return(GetDefaultOpenIdConfigurationEndpoint());
        }
        public void Authenticate(Uri authorizationUri, Uri redirectUri, RequestContext requestContext)
        {
            try
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
                {
                    asWebAuthenticationSession = new AuthenticationServices.ASWebAuthenticationSession(new NSUrl(authorizationUri.AbsoluteUri),
                                                                                                       redirectUri.Scheme, (callbackUrl, error) =>
                    {
                        if (error != null)
                        {
                            ProcessCompletionHandlerError(error);
                        }
                        else
                        {
                            ContinueAuthentication(callbackUrl.ToString());
                        }
                    });

                    asWebAuthenticationSession.Start();
                }

                else if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
                {
                    sfAuthenticationSession = new SFAuthenticationSession(new NSUrl(authorizationUri.AbsoluteUri),
                                                                          redirectUri.Scheme, (callbackUrl, error) =>
                    {
                        if (error != null)
                        {
                            ProcessCompletionHandlerError(error);
                        }
                        else
                        {
                            ContinueAuthentication(callbackUrl.ToString());
                        }
                    });

                    sfAuthenticationSession.Start();
                }

                else
                {
                    safariViewController          = new SFSafariViewController(new NSUrl(authorizationUri.AbsoluteUri), false);
                    safariViewController.Delegate = this;
                    viewController.InvokeOnMainThread(() =>
                    {
                        viewController.PresentViewController(safariViewController, false, null);
                    });
                }
            }
            catch (Exception ex)
            {
                requestContext.Logger.ErrorPii(ex);
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.AuthenticationUiFailedError,
                          "Failed to invoke SFSafariViewController",
                          ex);
            }
        }
 private static void Validate(InstanceDiscoveryResponse instanceDiscoveryResponse)
 {
     if (instanceDiscoveryResponse.TenantDiscoveryEndpoint == null)
     {
         throw MsalExceptionFactory.GetClientException(
                   instanceDiscoveryResponse.Error,
                   instanceDiscoveryResponse.ErrorDescription);
     }
 }
        /// <summary>
        /// Get the user logged in to Windows or throws
        /// </summary>
        /// <remarks>
        /// Win10 allows several identities to be logged in at once;
        /// select the first principal name that can be used
        /// </remarks>
        /// <returns>The username or throws</returns>
        public async Task <string> GetUserPrincipalNameAsync()
        {
            IReadOnlyList <User> users = await User.FindAllAsync();

            if (users == null || !users.Any())
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.CannotAccessUserInformationOrUserNotDomainJoined,
                          CoreErrorMessages.UapCannotFindDomainUser);
            }

            var getUserDetailTasks = users.Select(async u =>
            {
                object domainObj    = await u.GetPropertyAsync(KnownUserProperties.DomainName);
                string domainString = domainObj?.ToString();

                object principalObject     = await u.GetPropertyAsync(KnownUserProperties.PrincipalName);
                string principalNameString = principalObject?.ToString();

                return(new { Domain = domainString, PrincipalName = principalNameString });
            }).ToList();

            var userDetails = await Task.WhenAll(getUserDetailTasks).ConfigureAwait(false);

            // try to get a user that has both domain name and upn
            var userDetailWithDomainAndPn = userDetails.FirstOrDefault(
                d => !string.IsNullOrWhiteSpace(d.Domain) &&
                !string.IsNullOrWhiteSpace(d.PrincipalName));

            if (userDetailWithDomainAndPn != null)
            {
                return(userDetailWithDomainAndPn.PrincipalName);
            }

            // try to get a user that at least has upn
            var userDetailWithPn = userDetails.FirstOrDefault(
                d => !string.IsNullOrWhiteSpace(d.PrincipalName));

            if (userDetailWithPn != null)
            {
                return(userDetailWithPn.PrincipalName);
            }

            // user has domain name, but no upn -> missing Enterprise Auth capability
            if (userDetails.Any(d => !string.IsNullOrWhiteSpace(d.Domain)))
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.CannotAccessUserInformationOrUserNotDomainJoined,
                          CoreErrorMessages.UapCannotFindUpn);
            }

            // no domain, no upn -> missing User Info capability
            throw MsalExceptionFactory.GetClientException(
                      CoreErrorCodes.CannotAccessUserInformationOrUserNotDomainJoined,
                      CoreErrorMessages.UapCannotFindDomainUser);
        }
コード例 #14
0
        public void ParamValidation()
        {
            AssertException.Throws <ArgumentNullException>(() => MsalExceptionFactory.GetClientException(null, ExMessage));
            AssertException.Throws <ArgumentNullException>(() => MsalExceptionFactory.GetClientException("", ExMessage));

            AssertException.Throws <ArgumentNullException>(
                () => MsalExceptionFactory.GetServiceException(ExCode, "", new ExceptionDetail()));

            AssertException.Throws <ArgumentNullException>(
                () => MsalExceptionFactory.GetServiceException(ExCode, null, new ExceptionDetail()));
        }
        /// <inheritdoc/>
        public async Task <WsTrustResponse> GetWsTrustResponseAsync(
            WsTrustEndpoint wsTrustEndpoint,
            string wsTrustRequest,
            RequestContext requestContext)
        {
            var headers = new Dictionary <string, string>
            {
                { "ContentType", "application/soap+xml" },
                { "SOAPAction", (wsTrustEndpoint.Version == WsTrustVersion.WsTrust2005) ? XmlNamespace.Issue2005.ToString() : XmlNamespace.Issue.ToString() }
            };

            var body = new StringContent(
                wsTrustRequest,
                Encoding.UTF8, headers["ContentType"]);

            IHttpWebResponse resp = await _httpManager.SendPostForceResponseAsync(wsTrustEndpoint.Uri, headers, body, requestContext).ConfigureAwait(false);

            if (resp.StatusCode != System.Net.HttpStatusCode.OK)
            {
                string errorMessage = null;
                try
                {
                    errorMessage = WsTrustResponse.ReadErrorResponse(XDocument.Parse(resp.Body, LoadOptions.None), requestContext);
                }
                catch (System.Xml.XmlException)
                {
                    errorMessage = resp.Body;
                }

                throw MsalExceptionFactory.GetServiceException(
                          CoreErrorCodes.FederatedServiceReturnedError,
                          string.Format(
                              CultureInfo.CurrentCulture,
                              CoreErrorMessages.FederatedServiceReturnedErrorTemplate,
                              wsTrustEndpoint.Uri,
                              errorMessage),
                          new ExceptionDetail()
                {
                    StatusCode          = (int)resp.StatusCode,
                    ResponseBody        = resp.Body,
                    HttpResponseHeaders = resp.Headers
                });
            }

            try
            {
                return(WsTrustResponse.CreateFromResponse(resp.Body, wsTrustEndpoint.Version));
            }
            catch (System.Xml.XmlException ex)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.ParsingWsTrustResponseFailed, CoreErrorCodes.ParsingWsTrustResponseFailed, ex);
            }
        }
コード例 #16
0
        public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext)
        {
            bool shouldLogAsError = true;

            Exception serviceEx;

            try
            {
                var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);

                if (CoreErrorCodes.InvalidGrantError.Equals(msalTokenResponse.Error, StringComparison.OrdinalIgnoreCase))
                {
                    throw MsalExceptionFactory.GetUiRequiredException(
                              CoreErrorCodes.InvalidGrantError,
                              msalTokenResponse.ErrorDescription,
                              null,
                              ExceptionDetail.FromHttpResponse(response));
                }

                serviceEx = MsalExceptionFactory.GetServiceException(
                    msalTokenResponse.Error,
                    msalTokenResponse.ErrorDescription,
                    response);

                // For device code flow, AuthorizationPending can occur a lot while waiting
                // for the user to auth via browser and this causes a lot of error noise in the logs.
                // So suppress this particular case to an Info so we still see the data but don't
                // log it as an error since it's expected behavior while waiting for the user.
                if (string.Compare(msalTokenResponse.Error, OAuth2Error.AuthorizationPending,
                                   StringComparison.OrdinalIgnoreCase) == 0)
                {
                    shouldLogAsError = false;
                }
            }
            catch (SerializationException ex)
            {
                serviceEx = MsalExceptionFactory.GetClientException(CoreErrorCodes.UnknownError, response.Body, ex);
            }

            if (shouldLogAsError)
            {
                requestContext.Logger.ErrorPii(serviceEx);
            }
            else
            {
                requestContext.Logger.InfoPii(serviceEx);
            }

            throw serviceEx;
        }
        /// <summary>
        /// Gets the currently logged in user. Works for Windows when user is AD or AAD joined. Throws otherwise if cannot be found.
        /// </summary>
        public async Task <string> GetPlatformUserAsync()
        {
            string platformUsername = await _serviceBundle.PlatformProxy.GetUserPrincipalNameAsync().ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(platformUsername))
            {
                _requestContext.Logger.Error("Could not find UPN for logged in user.");

                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.UnknownUser,
                          CoreErrorMessages.UnknownUser);
            }

            _requestContext.Logger.InfoPii($"Logged in user detected with user name '{platformUsername}'", "Logged in user detected");
            return(platformUsername);
        }
コード例 #18
0
        /// <summary>
        ///
        /// </summary>
        protected override void OnResume()
        {
            base.OnResume();

            if (_restarted)
            {
                cancelRequest();
                return;
            }

            _restarted = true;

            string chromePackageWithCustomTabSupport = GetChromePackageWithCustomTabSupport(ApplicationContext);

            if (string.IsNullOrEmpty(chromePackageWithCustomTabSupport))
            {
                Intent browserIntent = new Intent(Intent.ActionView, Uri.Parse(_requestUrl));
                browserIntent.AddCategory(Intent.CategoryBrowsable);

                MsalLogger.Default.Warning(
                    "Browser with custom tabs package not available. " +
                    "Launching with alternate browser. See https://aka.ms/msal-net-system-browsers for details.");

                try
                {
                    StartActivity(browserIntent);
                }
                catch (ActivityNotFoundException ex)
                {
                    throw MsalExceptionFactory.GetClientException(
                              CoreErrorCodes.AndroidActivityNotFound,
                              CoreErrorMessages.AndroidActivityNotFound, ex);
                }
            }
            else
            {
                MsalLogger.Default.Info(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        "Browser with custom tabs package available. Using {0}. ",
                        chromePackageWithCustomTabSupport));

                CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().Build();
                customTabsIntent.Intent.SetPackage(chromePackageWithCustomTabSupport);
                customTabsIntent.LaunchUrl(this, Uri.Parse(_requestUrl));
            }
        }
コード例 #19
0
        protected override bool ExistsInValidatedAuthorityCache(string userPrincipalName)
        {
            if (string.IsNullOrEmpty(userPrincipalName))
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.UpnRequired,
                          CoreErrorMessages.UpnRequiredForAuthroityValidation);
            }

            if (ServiceBundle.ValidatedAuthoritiesCache.TryGetValue(CanonicalAuthority, out Authority authority))
            {
                var auth = (AdfsAuthority)authority;
                return(auth._validForDomainsList.Contains(GetDomainFromUpn(userPrincipalName)));
            }

            return(false);
        }
コード例 #20
0
        private static Exception ExtractErrorsFromTheResponse(HttpResponse response, ref bool shouldLogAsError)
        {
            Exception exceptionToThrow = null;

            // In cases where the end-point is not found (404) response.body will be empty.
            if (string.IsNullOrWhiteSpace(response.Body))
            {
                return(null);
            }

            var msalTokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(response.Body);

            if (msalTokenResponse?.Error == null)
            {
                return(null);
            }

            if (CoreErrorCodes.InvalidGrantError.Equals(msalTokenResponse.Error, StringComparison.OrdinalIgnoreCase))
            {
                exceptionToThrow = MsalExceptionFactory.GetUiRequiredException(
                    CoreErrorCodes.InvalidGrantError,
                    msalTokenResponse.ErrorDescription,
                    null,
                    ExceptionDetail.FromHttpResponse(response));
            }
            else
            {
                exceptionToThrow = MsalExceptionFactory.GetServiceException(
                    msalTokenResponse.Error,
                    msalTokenResponse.ErrorDescription,
                    response);
            }

            // For device code flow, AuthorizationPending can occur a lot while waiting
            // for the user to auth via browser and this causes a lot of error noise in the logs.
            // So suppress this particular case to an Info so we still see the data but don't
            // log it as an error since it's expected behavior while waiting for the user.
            if (string.Compare(msalTokenResponse.Error, OAuth2Error.AuthorizationPending,
                               StringComparison.OrdinalIgnoreCase) == 0)
            {
                shouldLogAsError = false;
            }

            return(exceptionToThrow);
        }
コード例 #21
0
        public static void CreateErrorResponse(HttpResponse response, RequestContext requestContext)
        {
            bool shouldLogAsError = true;

            var httpErrorCodeMessage = string.Format(CultureInfo.InvariantCulture, "HttpStatusCode: {0}: {1}", (int)response.StatusCode, response.StatusCode.ToString());

            requestContext.Logger.Info(httpErrorCodeMessage);

            Exception exceptionToThrow = null;

            try
            {
                exceptionToThrow = ExtractErrorsFromTheResponse(response, ref shouldLogAsError);
            }
            catch (SerializationException) // in the rare case we get an error response we cannot deserialize
            {
                exceptionToThrow = MsalExceptionFactory.GetServiceException(
                    CoreErrorCodes.NonParsableOAuthError,
                    CoreErrorMessages.NonParsableOAuthError,
                    response);
            }
            catch (Exception ex)
            {
                exceptionToThrow = MsalExceptionFactory.GetServiceException(CoreErrorCodes.UnknownError, response.Body, ex, response);
            }

            if (exceptionToThrow == null)
            {
                exceptionToThrow = response.StatusCode != HttpStatusCode.NotFound ?
                                   MsalExceptionFactory.GetServiceException(CoreErrorCodes.HttpStatusCodeNotOk, httpErrorCodeMessage, response) :
                                   MsalExceptionFactory.GetServiceException(CoreErrorCodes.HttpStatusNotFound, httpErrorCodeMessage, response);
            }

            if (shouldLogAsError)
            {
                requestContext.Logger.ErrorPii(exceptionToThrow);
            }
            else
            {
                requestContext.Logger.InfoPii(exceptionToThrow);
            }

            throw exceptionToThrow;
        }
        public async Task <WsTrustResponse> PerformWsTrustMexExchangeAsync(
            string federationMetadataUrl, string cloudAudienceUrn, UserAuthType userAuthType)
        {
            MexDocument mexDocument;

            try
            {
                mexDocument = await _serviceBundle.WsTrustWebRequestManager.GetMexDocumentAsync(
                    federationMetadataUrl, _requestContext).ConfigureAwait(false);
            }
            catch (XmlException ex)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.ParsingWsMetadataExchangeFailed,
                          CoreErrorMessages.ParsingMetadataDocumentFailed,
                          ex);
            }

            WsTrustEndpoint wsTrustEndpoint = userAuthType == UserAuthType.IntegratedAuth
                ? mexDocument.GetWsTrustWindowsTransportEndpoint()
                : mexDocument.GetWsTrustUsernamePasswordEndpoint();

            if (wsTrustEndpoint == null)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.WsTrustEndpointNotFoundInMetadataDocument,
                          CoreErrorMessages.WsTrustEndpointNotFoundInMetadataDocument);
            }

            _requestContext.Logger.InfoPii(
                string.Format(CultureInfo.InvariantCulture, "WS-Trust endpoint '{0}' being used from MEX at '{1}'", wsTrustEndpoint.Uri, federationMetadataUrl),
                "Fetched and parsed MEX");

            WsTrustResponse wsTrustResponse = await GetWsTrustResponseAsync(
                userAuthType,
                cloudAudienceUrn,
                wsTrustEndpoint,
                _usernameInput).ConfigureAwait(false);

            _requestContext.Logger.Info($"Token of type '{wsTrustResponse.TokenType}' acquired from WS-Trust endpoint");

            return(wsTrustResponse);
        }
コード例 #23
0
        public AndroidTokenCacheAccessor()
        {
            _accessTokenSharedPreference = Application.Context.GetSharedPreferences(AccessTokenSharedPreferenceName,
                                                                                    FileCreationMode.Private);
            _refreshTokenSharedPreference = Application.Context.GetSharedPreferences(RefreshTokenSharedPreferenceName,
                                                                                     FileCreationMode.Private);
            _idTokenSharedPreference = Application.Context.GetSharedPreferences(IdTokenSharedPreferenceName,
                                                                                FileCreationMode.Private);
            _accountSharedPreference = Application.Context.GetSharedPreferences(AccountSharedPreferenceName,
                                                                                FileCreationMode.Private);

            if (_accessTokenSharedPreference == null || _refreshTokenSharedPreference == null ||
                _idTokenSharedPreference == null || _accountSharedPreference == null)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.FailedToCreateSharedPreference,
                          "Fail to create SharedPreference");
            }
        }
        public async Task <UserRealmDiscoveryResponse> QueryUserRealmDataAsync(string userRealmUriPrefix)
        {
            var userRealmResponse = await _serviceBundle.WsTrustWebRequestManager.GetUserRealmAsync(
                userRealmUriPrefix,
                _usernameInput.UserName,
                _requestContext).ConfigureAwait(false);

            if (userRealmResponse == null)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.UserRealmDiscoveryFailed,
                          CoreErrorMessages.UserRealmDiscoveryFailed);
            }

            _requestContext.Logger.InfoPii(
                $"User with user name '{_usernameInput.UserName}' detected as '{userRealmResponse.AccountType}'",
                string.Empty);

            return(userRealmResponse);
        }
コード例 #25
0
        public static ClientInfo CreateFromJson(string clientInfo)
        {
            if (string.IsNullOrEmpty(clientInfo))
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.JsonParseError,
                          "client info is null");
            }

            try
            {
                return(JsonHelper.DeserializeFromJson <ClientInfo>(Base64UrlHelpers.DecodeToBytes(clientInfo)));
            }
            catch (Exception exc)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.JsonParseError,
                          "Failed to parse the returned client info.",
                          exc);
            }
        }
コード例 #26
0
        public void MsalClientException_FromCoreException()
        {
            // Act
            var msalException = MsalExceptionFactory.GetClientException(ExCode, ExMessage);

            // Assert
            var msalClientException = msalException as MsalClientException;

            Assert.AreEqual(ExCode, msalClientException.ErrorCode);
            Assert.AreEqual(ExMessage, msalClientException.Message);
            Assert.IsNull(msalClientException.InnerException);

            // Act
            string piiMessage = MsalExceptionFactory.GetPiiScrubbedDetails(msalException);

            // Assert
            Assert.IsFalse(string.IsNullOrEmpty(piiMessage));
            Assert.IsTrue(
                piiMessage.Contains(typeof(MsalClientException).Name),
                "The pii message should contain the exception type");
            Assert.IsTrue(piiMessage.Contains(ExCode));
            Assert.IsFalse(piiMessage.Contains(ExMessage));
        }
        private SecStatusCode Save(string account, string service, string generic, int type, string value)
        {
            SecRecord recordToSave = CreateRecord(account, service, generic, type, value);

            var secStatusCode = Update(recordToSave);

            if (secStatusCode == SecStatusCode.ItemNotFound)
            {
                secStatusCode = SecKeyChain.Add(recordToSave);
            }

            if (secStatusCode == SecStatusCode.MissingEntitlement)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.MissingEntitlements,
                          string.Format(
                              CultureInfo.InvariantCulture,
                              CoreErrorMessages.MissingEntitlements,
                              recordToSave.AccessGroup));
            }

            return(secStatusCode);
        }
        public async override Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, RequestContext requestContext)
        {
            returnedUriReady = new SemaphoreSlim(0);

            try
            {
                var agentIntent = new Intent(_coreUIParent.CallerActivity, typeof(AuthenticationAgentActivity));
                agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri);
                agentIntent.PutExtra("Callback", redirectUri.AbsoluteUri);
                _coreUIParent.CallerActivity.StartActivityForResult(agentIntent, 0);
            }
            catch (Exception ex)
            {
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.AuthenticationUiFailedError,
                          "AuthenticationActivity failed to start",
                          ex);
            }

            await returnedUriReady.WaitAsync().ConfigureAwait(false);

            return(authorizationResult);
        }
コード例 #29
0
        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 MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.InvalidJwtError,
                          CoreErrorMessages.IDTokenMustHaveTwoParts);
            }

            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 MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.JsonParseError,
                          CoreErrorMessages.FailedToParseIDToken,
                          exc);
            }

            return(idTokenBody);
        }
コード例 #30
0
        public static Authority CreateAuthority(IServiceBundle serviceBundle, string authority, bool validateAuthority)
        {
            authority = CanonicalizeUri(authority);
            ValidateAsUri(authority);

            switch (GetAuthorityType(authority))
            {
            case AuthorityType.Adfs:
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.InvalidAuthorityType,
                          "ADFS is not a supported authority");

            case AuthorityType.B2C:
                return(new B2CAuthority(serviceBundle, authority, validateAuthority));

            case AuthorityType.Aad:
                return(new AadAuthority(serviceBundle, authority, validateAuthority));

            default:
                throw MsalExceptionFactory.GetClientException(
                          CoreErrorCodes.InvalidAuthorityType,
                          "Unsupported authority type");
            }
        }