protected MobileServicePKCEAuthentication(MobileServiceClient client, string provider, string uriScheme, IDictionary <string, string> parameters) : base(client, provider, parameters) { if (client == null) { throw new ArgumentNullException("client"); } if (string.IsNullOrWhiteSpace(uriScheme)) { throw new ArgumentException("uriScheme"); } this.client = client; this.CodeVerifier = GetCodeVerifier(); this.CallbackUri = new Uri(MobileServiceUrlBuilder.CombileSchemeAndPath(uriScheme, "easyauth.callback")); var path = MobileServiceUrlBuilder.CombinePaths(LoginAsyncUriFragment, this.ProviderName); if (!string.IsNullOrEmpty(this.Client.LoginUriPrefix)) { path = MobileServiceUrlBuilder.CombinePaths(this.Client.LoginUriPrefix, this.ProviderName); } var loginParameters = parameters != null ? new Dictionary <string, string>(parameters) : new Dictionary <string, string>(); loginParameters.Add("post_login_redirect_url", this.CallbackUri.AbsoluteUri); loginParameters.Add("code_challenge", GetSha256Hash(this.CodeVerifier)); loginParameters.Add("code_challenge_method", "S256"); loginParameters.Add("session_mode", "token"); var loginQueryString = MobileServiceUrlBuilder.GetQueryString(loginParameters, false); var loginPathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, loginQueryString); this.LoginUri = new Uri(this.Client.MobileAppUri, loginPathAndQuery); if (this.Client.AlternateLoginHost != null) { this.LoginUri = new Uri(this.Client.AlternateLoginHost, loginPathAndQuery); } }