Пример #1
0
        /// <summary>
        /// Builds a XeroLogin URL for code flow, allows state and scope to be passed in.
        /// </summary>
        /// <returns>A valid initial redirect URI for Xero OAuth 2.0 authorisation flow.</returns>
        public string BuildLoginUri(string state, string scope)
        {
            var url = _xeroAuthorizeUri.CreateAuthorizeUrl(
                clientId: xeroConfiguration.ClientId,
                responseType: "code",
                redirectUri: xeroConfiguration.CallbackUri.AbsoluteUri,
                state: state,
                scope: scope
                );

            return(url);
        }
Пример #2
0
        protected async Task <string> DefaultGetAuthorizationCode(string authorizationEndpoint)
        {
            CurrentStateToken = GenerateAuthorizationStateToken();
            var request      = new RequestUrl(authorizationEndpoint);
            var authorizeUri = request.CreateAuthorizeUrl(ClientId, OidcConstants.ResponseTypes.Code, Scope, RedirectUriRoot, CurrentStateToken);

            var redirectUri = await AuthUriAcquirer.GetAuthorizationUriAsync(authorizeUri, RedirectUriRoot);

            if (string.IsNullOrEmpty(redirectUri))
            {
                return(null);
            }

            var returnedStateToken = StateCodeRegex.Match(redirectUri).Groups[1].Value;

            if (returnedStateToken != CurrentStateToken)
            {
                return(null);
            }

            var authCode = AuthCodeRegex.Match(redirectUri).Groups[1].Value;

            authCode = WebUtility.UrlDecode(authCode);
            return(authCode);
        }
Пример #3
0
        public ViewResult Login([FromQuery] string returnUrl)
        {
            var authorizeEndpoint = $"{_generalSettings.Authority}/connect/authorize";
            var requestUrl        = new RequestUrl(authorizeEndpoint);
            var codeVerifier      = CryptoRandom.CreateUniqueId(32);

            if (TempData.ContainsKey(OidcConstants.TokenRequest.CodeVerifier))
            {
                TempData.Remove(OidcConstants.TokenRequest.CodeVerifier);
            }
            TempData.Add(OidcConstants.TokenRequest.CodeVerifier, codeVerifier);
            string codeChallenge;

            using (var sha256 = SHA256.Create()) {
                var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                codeChallenge = Base64Url.Encode(challengeBytes);
            }
            var authorizeUrl = requestUrl.CreateAuthorizeUrl(
                clientId: _clientSettings.Id,
                responseType: OidcConstants.ResponseTypes.CodeIdToken,
                codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256,
                codeChallenge: codeChallenge,
                responseMode: OidcConstants.ResponseModes.FormPost,
                redirectUri: $"{_generalSettings.Host}/account/auth-callback",
                nonce: Guid.NewGuid().ToString(),
                scope: string.Join(" ", _clientSettings.Scopes),
                state: !string.IsNullOrEmpty(returnUrl) ? Convert.ToBase64String(Encoding.UTF8.GetBytes(returnUrl)) : null
                );

            return(View(new LoginViewModel {
                AuthorizeUrl = authorizeUrl
            }));
        }
        public async Task <string> AuthenticateExternalUser(string clientId)
        {
            try
            {
                var idToken = this.Request.Headers["id"];

                if (string.IsNullOrEmpty(idToken))
                {
                    throw new Exception("No ID Token supplied");
                }

                var requestUrl  = new RequestUrl(Addresses.InoxicoSTSAuth);
                var redirectUrl = requestUrl.CreateAuthorizeUrl(
                    clientId: OAuth.InoxicoClientId,
                    responseType: "id_token token",
                    scope: "openid profile read write offline_access",
                    redirectUri: Addresses.IntendedLocation,
                    state: EncodeState(idToken, clientId),
                    nonce: Guid.NewGuid().ToString("N"),
                    acrValues: $"idp:{OAuth.IdentityProvider_ThirdParty}");

                return(redirectUrl);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
Пример #5
0
        /// <summary>
        /// Uses the Embedded Broswer for login and auto process the AccessCode
        /// </summary
        public async Task <BrowserResultType> SignIn(OAuthSettings oAuthApplication, OAuthToken token)
        {
            var request = new RequestUrl(authorizationUrl);
            var url     = request.CreateAuthorizeUrl(
                clientId: oAuthApplication.ClientID,
                responseType: OidcConstants.ResponseTypes.Code,
                scope: _scope,
                state: oAuthApplication.ApplicationID.ToString(),
                redirectUri: oAuthApplication.ReturnUrl);

            var Browser        = new HMRC.Browser.WinFormsBroswer();
            var browserOptions = new BrowserOptions(url, "", SuccessTitle);

            browserOptions.DisplayMode = DisplayMode.Visible;

            var browserResult = await Browser.InvokeAsync(browserOptions);

            if (browserResult.ResultType == BrowserResultType.Success)
            {
                var r = browserResult.Response.Split('&');
                Dictionary <String, String> p = new Dictionary <string, string>();
                foreach (var item in r)
                {
                    var r1 = item.Split('=');
                    p.Add(r1[0], r1[1]);
                }
                string code = p[SuccessTitle];
                ProcessAuthorizationCode(code, oAuthApplication, token);
            }
            return(browserResult.ResultType);
        }
Пример #6
0
        public Uri GetLoginUri(Uri redirectUri, string state)
        {
            var request     = new RequestUrl(authorizationEndpoint);
            var lower       = string.Join(" ", scopes).ToLower();
            var absoluteUri = redirectUri.AbsoluteUri;
            var state1      = state.NullIfEmptyOrWhitespace();
            var nonce       = Guid.NewGuid().ToString("N");

            return(new Uri(request.CreateAuthorizeUrl(clientId, "id_token", lower, absoluteUri, state1, nonce, responseMode: "form_post")));
        }
Пример #7
0
        /// <summary>
        /// Builds a XeroLogin URL
        /// </summary>
        /// <returns>valid URI for login</returns>
        public string BuildLoginUri()
        {
            var url = xeroAuthorizeUri.CreateAuthorizeUrl(
                clientId: xeroConfiguration.ClientId,
                responseType: "code", //hardcoded authorisation code for now.
                redirectUri: xeroConfiguration.CallbackUri.AbsoluteUri,
                state: xeroConfiguration.State,
                scope: xeroConfiguration.Scope
                );

            return(url);
        }
Пример #8
0
        protected string GetAuthenticationURL()
        {
            var ru = new RequestUrl($"http://{Backend.BASE_URL}/connect/authorize");

            var url = ru.CreateAuthorizeUrl(
                clientId: "clientApp",
                responseType: "code id_token",
                redirectUri: "https://localhost/signin-oidc",
                nonce: "xyz",
                scope: "openid offline_access profile resourceApi");

            return(url);
        }
Пример #9
0
        private string GetLoginUrl(string redirectUrl, string nonce, string state)
        {
            var config = GetOpenIdConnectConfiguration();

            var requestUrl = new RequestUrl(config.AuthorizationEndpoint);

            return(requestUrl.CreateAuthorizeUrl(GetAttributeValue(AttributeKey.ApplicationId),
                                                 OidcConstants.ResponseTypes.Code,
                                                 GetScopes(),
                                                 $"{redirectUrl}",
                                                 state,
                                                 nonce));
        }
Пример #10
0
        public void OnGet()
        {
            var xeroAuthorizeUri = new RequestUrl("https://login.xero.com/identity/connect/authorize");
            var url = xeroAuthorizeUri.CreateAuthorizeUrl(
                clientId: GlobalConstant.ClientId,
                responseType: "code", //hardcoded authorisation code for now.
                redirectUri: GlobalConstant.RedirectUrl,
                state: "your state",
                scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access"
                );

            ViewData["XeroAuthorizeUrl"] = url;
        }
Пример #11
0
        /// <summary>
        /// Gets the token.
        /// </summary>
        /// <returns>System.String.</returns>
        public string GetToken()
        {
            var xeroAuthorizeUri = new RequestUrl(XeroUrl.IdentityServerAuthorize);
            var url = xeroAuthorizeUri.CreateAuthorizeUrl(
                clientId: _settings.ClientId,
                responseType: "code", //hardcoded authorisation code for now.
                redirectUri: "https://localhost:5001/oauth",
                state: "",
                scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access"
                );

            return(url);
        }
Пример #12
0
        internal string GenerateAuthorizationCodeUrl()
        {
            var authorizeEndpointUrl = new RequestUrl(this.ApplicationConfiguration.AuthorizeEndpoint);
            var url = authorizeEndpointUrl.CreateAuthorizeUrl(
                clientId: this.ApplicationConfiguration.ClientId,
                scope: this.ApplicationConfiguration.Scope,
                responseType: OidcConstants.ResponseTypes.Code,
                responseMode: OidcConstants.ResponseModes.Fragment,
                redirectUri: this.ApplicationConfiguration.RedirectUri,
                state: CryptoRandom.CreateUniqueId(),
                nonce: CryptoRandom.CreateUniqueId());

            return(url);
        }
Пример #13
0
        /// <summary>
        /// Created a Login URL incase you want to Call a different Browser from SignIn()
        /// </summary>
        public string GetSigninURL(OAuthSettings oAuthApplication)
        {
            var request = new RequestUrl(authorizationUrl);
            var url     = request.CreateAuthorizeUrl(
                clientId: oAuthApplication.ClientID,
                responseType: OidcConstants.ResponseTypes.Code,
                scope: _scope,
                state: oAuthApplication.ApplicationID.ToString(),
                redirectUri: oAuthApplication.ReturnUrl);

            //Wish I could send this in!
            //UserName = oAuthApplication.UserID,
            //Password = oAuthApplication.Password,
            return(url);
        }
Пример #14
0
        /// <summary>
        /// Creates the authorization request and shows the popup with the Web View.
        /// When the login is succesfully complete triggers you the LoginDone event.
        /// </summary>
        public void Login(string scope, string responseType)
        {
            const string redirectUri = "oob://localhost/wpf.webview.client";

            var request = new RequestUrl($"{AppSettings.Settings.Endpoint}identity/connect/authorize");

            var startUrl = request.CreateAuthorizeUrl(
                clientId: AppSettings.Settings.ClientId,
                responseType: responseType,
                scope: scope,
                redirectUri: redirectUri,
                nonce: CryptoRandom.CreateUniqueId());

            _login       = new LoginWebView();
            _login.Done += _login_Done;
            _login.Show();
            _login.Start(new Uri(startUrl), new Uri(redirectUri));
        }
Пример #15
0
        public ContentResult Get()
        {
            var xeroAuthorizeUri = new RequestUrl("https://login.xero.com/identity/connect/authorize");
            var url = xeroAuthorizeUri.CreateAuthorizeUrl(
                clientId: clientId,
                responseType: "code", //hardcoded authorisation code for now.
                redirectUri: redirectUrl,
                state: "your state",
                scope: "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access"
                );

            return(new ContentResult
            {
                ContentType = "text/html",
                StatusCode = (int)HttpStatusCode.OK,
                Content = String.Format("<html><head></head><body><a href ='{0}'>Connect to Xero</a></body></html>", url)
            });
        }
        /// <summary>
        /// 远程登录
        /// </summary>
        /// <returns></returns>
        public async Task <ActionResult> RemoteLogin()
        {
            var client = new DiscoveryClient("http://10.37.11.12:7000");

            client.Policy.RequireHttps = false;
            var doc = await client.GetAsync();

            var request = new RequestUrl(doc.AuthorizeEndpoint);
            var url     = request.CreateAuthorizeUrl(
                clientId: "netfx.client4",
                responseType: OidcConstants.ResponseTypes.CodeIdToken,
                responseMode: OidcConstants.ResponseModes.FormPost,
                redirectUri: "http://10.37.11.12:6004/Home/CallBack",
                scope: "netfx.api.TEST netcore.api.TEST openid",
                state: CryptoRandom.CreateUniqueId(),
                nonce: CryptoRandom.CreateUniqueId());

            return(Redirect(url));//302重定向到远程服务器登录
        }
        public async Task <bool> SignOut(string accessToken)
        {
            var result        = false;
            var introspection = await IdentityIntrospectionService.IntrospectToken(accessToken);

            var discovery = await DiscoveryService.GetDiscovery();

            var requestUrl = new RequestUrl(discovery.AuthorizeEndpoint);
            var url        = requestUrl.CreateAuthorizeUrl(Config.ClientId, "id_token", "openid email TSAPI");

            using (var client = new HttpClient())
            {
                var response = await client.GetAsync(url);

                result = response.StatusCode == System.Net.HttpStatusCode.OK;
            }

            return(result);
        }
Пример #18
0
        private async Task <TokenResponse> TestAuthCode(ClientConfig clientConfig, HttpClient client, string discoTokenEndpoint, string discoAuthorizeEndpoint)
        {
            var ru = new RequestUrl(discoAuthorizeEndpoint);

            string codeVerifier = CryptoRandom.CreateUniqueId(50);
            string codeChallenge;

            using (var sha256 = SHA256.Create())
            {
                var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                codeChallenge = Base64Url.Encode(challengeBytes);
            }

            var url = ru.CreateAuthorizeUrl(
                codeChallenge: codeChallenge,
                codeChallengeMethod: "S256",
                clientId: clientConfig.Id,
                responseType: "code",
                redirectUri: clientConfig.RedirectUris[0],
                scope: string.Join(" ", clientConfig.AllowedScopes));

            OpenUrl(url);
            _logger.LogInformation(url);
            //dopo il login l'utente viene rediretto alla pagina del redirectUri e tra i parametri in querystring c'è il code
            _logger.LogInformation("insert code:");
            var code = Console.ReadLine();

            if (string.IsNullOrWhiteSpace(code))
            {
                code = "code_missing";
            }
            return(await client.RequestAuthorizationCodeTokenAsync(
                       new AuthorizationCodeTokenRequest
            {
                Address = discoTokenEndpoint,
                ClientId = clientConfig.Id,
                ClientSecret = clientConfig.Password,
                RedirectUri = clientConfig.RedirectUris[0],
                Code = code,
                CodeVerifier = codeVerifier
            }));
        }
Пример #19
0
        public async Task <IActionResult> LoginImplicitGrant(LoginViewModel model, string state, string client_id, string response_type, string scope, string returnUrl)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : false);

                if (result.Succeeded)
                {
                    _logger.LogInformation("User logged in.");
                    //Change for proper domain
                    var request = new RequestUrl("https://0c574e90.ngrok.io/connect/authorize");
                    var url     = request.CreateAuthorizeUrl(
                        clientId:     "alexa",
                        scope: scope,
                        responseType: OidcConstants.ResponseTypes.IdTokenToken,
                        redirectUri: returnUrl,
                        state:       state,
                        nonce:       CryptoRandom.CreateUniqueId());

                    //returnUrl + "#state=" + state + "&access_token=" + "&token_type="
                    return(Redirect(url));
                }
                if (result.RequiresTwoFactor)
                {
                    return(RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe }));
                }
                if (result.IsLockedOut)
                {
                    _logger.LogWarning("User account locked out.");
                    return(RedirectToAction(nameof(Lockout)));
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return(View(model));
                }
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
Пример #20
0
        /// <inheritdoc cref="IUserApiClient.SigninAsync" />
        public async Task SigninAsync()
        {
            var pkce  = crypto.CreatePkceData();
            var disco = await cache.GetAsync();

            var url  = new RequestUrl(disco.AuthorizeEndpoint);
            var auth = url.CreateAuthorizeUrl(
                options.ClientId,
                OidcConstants.ResponseTypes.Code,
                GetScopes(options.Scopes),
                options.RedirectUri,
                state: pkce.CodeVerifier,
                responseMode: OidcConstants.ResponseModes.Query,
                codeChallenge: pkce.CodeChallenge,
                codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256,
                uiLocales: CultureInfo.CurrentUICulture.EnglishName
                );

            uri.NavigateTo(auth);
        }
Пример #21
0
        public async Task <string> CreateAuthorizeUrlAsync(Microsoft.Bot.Connector.IActivity activity)
        {
            var doc = await GetDiscoveryClient();

            var request = new RequestUrl(doc.AuthorizeEndpoint);
            var extra   = new Dictionary <string, string>
            {
                { OidcConstants.TokenRequest.ClientSecret, "secret" }
            };
            var authorizeUrl = request.CreateAuthorizeUrl(
                clientId: "Bot",
                responseType: OidcConstants.ResponseTypes.CodeIdToken,
                responseMode: OidcConstants.ResponseModes.FormPost,
                redirectUri: signinUrl,
                scope: "openid profile offline_access orders basket marketing locations",
                state: AuthData.Encode(activity.Recipient.Id, activity.ChannelId, activity.From.Id, activity.Conversation.Id, activity.ServiceUrl),
                nonce: CryptoRandom.CreateUniqueId(),
                extra: extra);

            return(authorizeUrl);
        }
Пример #22
0
        public async Task <string> AuthorizeUrl()
        {
            using (HttpClient client = httpClientFactory.CreateClient())
            {
                DiscoveryResponse disco = await client.GetDiscoveryDocumentAsync(Utils.Linked.Identity);

                if (disco.IsError)
                {
                    return(null);
                }

                var    ru  = new RequestUrl(disco.AuthorizeEndpoint);
                string url = ru.CreateAuthorizeUrl(
                    clientId: Utils.IdentityClient.ClientId,
                    responseType: "code",
                    scope: "openid profile email api",
                    redirectUri: Utils.ClientIdentityRedirectUri
                    );
                return(url);
            }
        }
Пример #23
0
        //https://auth0.com/docs/flows/concepts/auth-code-pkce
        public async Task <(string AuthorizeUrl, string CodeVerifier)> CreateAuthorizeUrlAsync(HttpContext context)
        {
            await LoadEndpointsAsync();

            var originalPathBase = context.Features.Get <IAuthenticationFeature>()?.OriginalPathBase ?? context.Request.PathBase;
            var redirectUri      = context.Request.Scheme + "://" + context.Request.Host + originalPathBase + signedInCallbackPath;

            var ru = new RequestUrl(authorizeEndpoint);

            var pkce = GeneratePKCEValues();

            var url = ru.CreateAuthorizeUrl(
                clientId: clientId,
                responseType: responseType,
                redirectUri: redirectUri,
                nonce: CryptoRandom.CreateUniqueId(32),
                codeChallengeMethod: pkce.CodeChallengeMethod,
                codeChallenge: pkce.CodeChallenge,
                scope: scopes);

            return(url, pkce.CodeVerifier);
        }
        private void PrepareAuthorizeRequest(DiscoveryDocumentResponse disco,
                                             out string codeVerifier, out string authorizeUrl)
        {
            var cvBytes = GetCodeVerifier();

            codeVerifier = Encoding.UTF8.GetString(cvBytes);
            var codeChallenge = GetCodeChallenge(cvBytes);
            var nonce         = GetNonce();
            var state         = GetState();

            var ru = new RequestUrl(disco.AuthorizeEndpoint);

            authorizeUrl = ru.CreateAuthorizeUrl(
                clientId: _oidcOptions.ClientId,
                responseType: _oidcOptions.ResponseType,
                redirectUri: $"{ _oidcOptions.RedirectUri}",
                nonce: nonce,
                state: state,
                codeChallenge: codeChallenge,
                codeChallengeMethod: _oidcOptions.CodeChallengeMethod,
                scope: string.Join(" ", _oidcOptions.Scopes)
                );
        }
Пример #25
0
        static async Task AuthorizeUrl()
        {
            try
            {
                var codeVerifier  = CryptoRandom.CreateUniqueId(32);
                var stateVerifier = CryptoRandom.CreateUniqueId(32);
                var nonceVerifier = CryptoRandom.CreateUniqueId(32);
                // discover endpoints from metadata
                var client = new HttpClient();
                var disco  = await client.GetDiscoveryDocumentAsync("https://localhost:44303/");

                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    return;
                }



                var ru           = new RequestUrl("https://localhost:44303/connect/authorize");
                var authorizeUrl = ru.CreateAuthorizeUrl(clientId: "d84d0a966e0b470facebd7a6dfa8b6b1",
                                                         responseType: "code",
                                                         scope: "openid profile offline_access awesomecareapi",
                                                         redirectUri: "https://localhost:44372/signin-oidc",
                                                         responseMode: "form_post",
                                                         codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256,
                                                         codeChallenge: codeVerifier.ToSha256(),
                                                         state: stateVerifier.ToSha256(),
                                                         nonce: nonceVerifier.ToSha256()
                                                         );
            }
            catch (Exception ex)
            {
                throw;
            }
        }
Пример #26
0
        public static void RedirectToAuthority(string returnUrl)
        {
            var authorizeEndpoint = $"{OAuthConfiguration.Authority}/{OAuthConfiguration.AuthorizeEndpointPath}";
            var stateProvider     = new StateProvider <string>();
            var currentPath       = returnUrl ?? string.Empty;
            var requestUrl        = new RequestUrl(authorizeEndpoint);

            // Create the url to Identity Server's authorize endpoint.
            var authorizeUrl = requestUrl.CreateAuthorizeUrl(
                clientId: OAuthConfiguration.ClientId,
                responseType: (OAuthConfiguration.ResponseType == "CodeIdToken")? OidcConstants.ResponseTypes.CodeIdToken : OidcConstants.ResponseTypes.Code,
                redirectUri: $"{OAuthConfiguration.Host}/SignInOidc.ashx",
                nonce: Guid.NewGuid().ToString(), // Identity Server will echo back the nonce value in the identity token (this is for replay protection).
                scope: OAuthConfiguration.Scopes.Join(" "),
                state: stateProvider.CreateState(currentPath)
                );

            if (!HttpContext.Current.Response.IsRequestBeingRedirected)
            {
                // Redirect the user to the authority.
                HttpContext.Current.Response.Redirect(authorizeUrl);
            }
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
Пример #27
0
        public async Task <IActionResult> OnGetOrPost()
        {
            if (string.IsNullOrWhiteSpace(Issuer))
            {
                _logger.LogError(new ArgumentNullException(nameof(Issuer)), $"{nameof(Issuer)} is missing.");
                return(BadRequest());
            }

            if (string.IsNullOrWhiteSpace(LoginHint))
            {
                _logger.LogError(new ArgumentNullException(nameof(LoginHint)), $"{nameof(LoginHint)} is missing.");
                return(BadRequest());
            }

            if (string.IsNullOrWhiteSpace(LtiMessageHint))
            {
                _logger.LogError(new ArgumentNullException(nameof(LtiMessageHint)), $"{nameof(LtiMessageHint)} is missing.");
                return(BadRequest());
            }

            if (string.IsNullOrWhiteSpace(TargetLinkUri))
            {
                _logger.LogError(new ArgumentNullException(nameof(TargetLinkUri)), $"{nameof(TargetLinkUri)} is missing.");
                return(BadRequest());
            }

            // Get the platform settings
            var platform = await _context.GetPlatformByIssuerAsync(Issuer);

            if (platform == null)
            {
                _logger.LogError($"Issuer not found [{Issuer}].");
                return(BadRequest());
            }

            // RPs MUST verify the value of the target_link_uri to prevent being
            // used as an open redirector to external sites.
            if (!Uri.TryCreate(TargetLinkUri, UriKind.Absolute, out var targetLinkUri))
            {
                _logger.LogError($"Invalid target_link_uri [{TargetLinkUri}].");
                return(BadRequest());
            }

            if (targetLinkUri.Host != Request.Host.Host)
            {
                _logger.LogError($"Invalid target_link_uri [{TargetLinkUri}].");
                return(BadRequest());
            }

            // Create a unique nonce for this flow
            var nonce = CryptoRandom.CreateUniqueId();

            // Consider using a state JWT as described in
            // https://tools.ietf.org/html/draft-bradley-oauth-jwt-encoded-state-09
            var state = CryptoRandom.CreateUniqueId();

            // Store the nonce and flow so they can be validated when the id_token
            // is posted back to the tool by the Authorization Server.
            _stateContext.AddState(nonce, state);

            var ru  = new RequestUrl(platform.AuthorizeUrl);
            var url = ru.CreateAuthorizeUrl
                      (
                clientId: platform.ClientId,
                responseType: OidcConstants.ResponseTypes.IdToken,

                // POST the id_token directly to the tool's launch URL
                responseMode: OidcConstants.ResponseModes.FormPost,
                redirectUri: TargetLinkUri,

                // Per IMS guidance
                scope: OidcConstants.StandardScopes.OpenId,

                // Consider checking state after redirect to make sure the state was not tampared with
                state: state,

                // The userId
                loginHint: LoginHint,

                // Checking nonce at launch to make sure the id_token came from this flow and not direct
                nonce: nonce,

                // No user interaction
                prompt: "none",

                // The messagedId (i.e. resource link id or deep link id)
                extra: new { lti_message_hint = LtiMessageHint }
                      );

            _logger.LogInformation("Requesting id_token.");

            return(Redirect(url));
        }
Пример #28
0
        public static string getUrl(ulong id, Action <MSScopeOptions> action = null)
        {
            var msScope = new MSScopeOptions();

            if (action == null)
            {
                action = x =>
                {
                    x.OpenId    = true;
                    x.User_Read = true;
                }
            }
            ;
            action(msScope);
            string stateValue = id.ToString();

            stateValue += "." + Program.ToBase64(msScope.ToString());
            var ru  = new RequestUrl($"https://login.microsoftonline.com/{Program.Configuration["ms_auth:tenant_id"]}/oauth2/v2.0/authorize");
            var url = ru.CreateAuthorizeUrl(
                clientId: Program.Configuration["ms_auth:client_id"],
                responseType: "id_token code",
                responseMode: "form_post",
                redirectUri: Handler.LocalAPIUrl + "/login/msoauth",
                nonce: DateTime.Now.DayOfYear.ToString(),
                state: stateValue,
                scope: msScope.GetScopes());

            Console.WriteLine(url);
            return(url);
        }

        bool actOnUserProfile(TokenResponse response, HttpClient client)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");

            request.Headers.Add("Authorization", "Bearer " + response.AccessToken);
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var identityResponse = client.SendAsync(request).Result;

            if (!identityResponse.IsSuccessStatusCode)
            {
                RespondRaw("Could not complete Oauth", identityResponse.StatusCode);
                return(false);
            }
            var content = identityResponse.Content.ReadAsStringAsync().Result;
            var jobj    = JObject.Parse(content);

            Context.User.VerifiedEmail = jobj["mail"].ToObject <string>();
            Context.User.IsVerified    = true;
            if (string.IsNullOrWhiteSpace(Context.User.Name) || Context.User.Name == Context.User.Id.ToString())
            {
                Context.User.OverrideName = jobj["displayName"].ToObject <string>();
            }
            var service = Program.Services.GetRequiredService <ChessService>();

            if (service != null && !Context.User.ServiceUser && !Context.User.GeneratedUser)
            {
                using var db = Program.Services.GetRequiredService <ChessDbContext>();
                string name     = $"{jobj["givenName"]} {jobj["surname"].ToObject<string>()[0]}";
                var    existing = db.Players.AsQueryable().FirstOrDefault(x => x.Name == name && !x.IsBuiltInAccount);
                if (existing != null)
                {
                    existing.ConnectedAccount = Context.User.Id;
                }
                else
                {
                    var chs = db.Players.AsQueryable().FirstOrDefault(x => x.DiscordAccount == ChessService.cast(Context.User.Id) && !x.IsBuiltInAccount);
                    if (chs != null)
                    {
                        chs.Name = name;
                    }
                }
                service.OnSave();
            }
            return(true);
        }

        bool actOnTeams(TokenResponse response, HttpClient client)
        {
            var teamsRequest = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/joinedTeams");

            teamsRequest.Headers.Add("Authorization", "Bearer " + response.AccessToken);
            teamsRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var teamsResponse = client.SendAsync(teamsRequest).Result;

            if (!teamsResponse.IsSuccessStatusCode)
            {
                RespondRaw("Could not retrieve your teams information", teamsResponse.StatusCode);
                return(false);
            }
            var content    = teamsResponse.Content.ReadAsStringAsync().Result;
            var jobj       = JObject.Parse(content);
            var jvalue     = jobj["value"];
            var teamsArray = (JArray)jvalue;
            Dictionary <string, string> classes = new Dictionary <string, string>();

            foreach (JToken jTeam in teamsArray)
            {
                var name  = jTeam["displayName"].ToObject <string>();
                var split = name.Split('-');
                if (split.Length != 2)
                {
                    continue;
                }
                // class - Subject
                // eg
                // 1Mt3 - Maths
                classes[split[0].Trim()] = split[1].Trim();
            }
            Context.User.Classes = classes;
            return(true);
        }
Пример #29
0
        public async Task <TokenResponse> Login(LoginSettings loginSettings)
        {
            _log($"Logging in user {loginSettings.UserName} to {loginSettings.Authority}");

            var httpClient = new HttpClient(

                // We're following the auto-redirects explicitly.
                // The http client handler can also follow redirects, but then we can't intercept the request to the return url.
                new AutoFollowRedirectHandler(

                    // Handler that intercepts the requests to the return url, so the return url
                    // doesn't actually have to be valid (just registered with auth0)
                    new InterceptRedirectBackHandler(
                        loginSettings.RedirectUri.Host,

                        // Actual http handler that invokes auth0
                        new HttpClientHandler()
                        )
                    )
                );

            // Retrieve the discovery document. In theory we could hard-code the url's,
            // but this follows the standards better.
            var disco = await httpClient.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
            {
                Address = loginSettings.Authority.ToString(),
            });

            if (disco.IsError)
            {
                // Verify that the authority is available"
                throw new InvalidOperationException($"Failed to access authority discovery document: {disco.HttpStatusCode}: {disco.Error}");
            }

            // Step 1: Create and go to authorize url
            var request      = new RequestUrl(disco.AuthorizeEndpoint);
            var cryptoHelper = new CryptoHelper();
            var pkce         = cryptoHelper.CreatePkceData();
            var clientId     = loginSettings.ClientId;

            var authorizeUrl = request.CreateAuthorizeUrl(
                clientId,
                OidcConstants.ResponseTypes.Code,
                responseMode: OidcConstants.ResponseModes.Query,
                redirectUri: loginSettings.RedirectUri.ToString(),
                codeChallenge: pkce.CodeChallenge,
                codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256,
                scope: string.Join(" ", loginSettings.Scopes),
                extra: new
            {
                audience = loginSettings.Audience
            });

            _log("  - Login Step 1: Create and go to authorize url: " + authorizeUrl);
            var response = await httpClient.GetAsync(authorizeUrl);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new InvalidOperationException($"Invalid response code in Step 1. StatusCode: {response.StatusCode} authorize url: {authorizeUrl}.");
            }

            // Get the request querystring to extract the state property
            var query = QueryHelpers.ParseQuery(response.RequestMessage.RequestUri.Query);
            var state = query["state"].ToString();


            // The spec doesn't say where to post the login details to
            // but it's at /usernamepassword/login
            var loginPage = loginSettings.Authority.GetLeftPart(System.UriPartial.Authority) + "/usernamepassword/login";

            _log("  - Login Step 2: Post login details to login page: " + loginPage);
            // Create a json post to that url with the riight properties
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, loginPage)
            {
                Content = new StringContent(JsonConvert.SerializeObject(new
                {
                    client_id    = clientId,
                    redirect_uri = loginSettings.RedirectUri.ToString(),
                    tenant       = loginSettings.Auth0Tenant,
                    connection   = loginSettings.Connection,
                    username     = loginSettings.UserName,
                    state        = state,
                    password     = loginSettings.Password,
                }), Encoding.UTF8, "application/json")
            };

            response = await httpClient.SendAsync(requestMessage);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new InvalidOperationException($"Invalid response code in Step 2. StatusCode: {response.StatusCode} login page: {loginPage}. {await response.Content.ReadAsStringAsync()}");
            }


            var doc = new HtmlDocument();

            doc.LoadHtml(await response.Content.ReadAsStringAsync());

            var form   = doc.DocumentNode.FirstChild;
            var action = form.Attributes["action"].Value;

            _log($"  - Login Step 3: The response contains a form. Post it to: {action}");
            var inputElements = form
                                .SelectNodes("input")
                                .Select(x =>
                                        new KeyValuePair <string, string>
                                        (
                                            x.Attributes["name"].Value,
                                            HttpUtility.HtmlDecode(x.Attributes["value"].Value)
                                        )
                                        );

            requestMessage = new HttpRequestMessage(HttpMethod.Post, action)
            {
                Content = new FormUrlEncodedContent(inputElements)
            };

            response = await httpClient.SendAsync(requestMessage);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new InvalidOperationException($"Invalid response code in Step 3. StatusCode: {response.StatusCode} action: {action}. {await response.Content.ReadAsStringAsync()}");
            }


            var location = response.RequestMessage.RequestUri;

            _log($"  - Login Step 4: We are now redirected at the redirect-page. Get the authorization code from url: {location}");
            query = QueryHelpers.ParseQuery(location.Query);
            if (!query.TryGetValue("code", out var code))
            {
                throw new InvalidOperationException("Failed step 4. Could not find code in url: " + location);
            }

            _log($"  - Login Step 5: Swap authorization code for an access token. ");
            var tokenResponse = await httpClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
            {
                Address = disco.TokenEndpoint,

                ClientId = clientId,
                ClientCredentialStyle = ClientCredentialStyle.AuthorizationHeader,
                ClientSecret          = loginSettings.ClientSecret,
                Code         = code,
                RedirectUri  = loginSettings.RedirectUri.ToString(),
                CodeVerifier = pkce.CodeVerifier,
                Parameters   = new Dictionary <string, string>()
            });

            if (tokenResponse.HttpStatusCode != HttpStatusCode.OK)
            {
                throw new InvalidOperationException($"Failed step 5. statuscode not ok: {tokenResponse.HttpStatusCode} {tokenResponse.ErrorDescription} {tokenResponse.Error}");
            }

            return(tokenResponse);
        }