public async Task missing_identity_token_on_token_response_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                //{ "id_token", "id_token" },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("Error validating token response: Identity token is missing on token response.");
        }
Beispiel #2
0
        public async Task malformed_identity_token_on_token_response_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", "id_token" },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().StartWith("Error validating token response: Error validating identity token: System.ArgumentException: IDX10709: JWT is not well formed");
        }
        public async Task Malformed_identity_token_on_token_response_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", "id_token" },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().Contain("invalid_jwt");
        }
        public async Task no_keyset_for_identity_token_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", Crypto.UntrustedIdentityToken },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().StartWith("Error validating token response: Error validating identity token: Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500: Signature validation failed. No security keys were provided to validate the signature");
        }
Beispiel #5
0
        public async Task No_keyset_for_identity_token_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", Crypto.UntrustedIdentityToken },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().Contain("IDX10501");
        }
        public async Task invalid_nonce_should_fail()
        {
            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var key = Crypto.CreateKey();

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);

            var frontChannelJwt = Crypto.CreateJwt(key, "https://authority", "client",
                                                   new Claim("sub", "123"),
                                                   new Claim("nonce", "invalid"),
                                                   new Claim("c_hash", Crypto.HashData("code")));

            var url = $"?state={state.State}&code=code&id_token={frontChannelJwt}";

            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("Invalid nonce.");
        }
        public async Task Extra_parameters_on_backchannel_should_be_sent()
        {
            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&code=bar";
            var idToken = Crypto.CreateJwt(null, "https://authority", "client",
                                           new Claim("at_hash", Crypto.HashData("token")),
                                           new Claim("sub", "123"));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            var handler = new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            _options.BackchannelHandler = handler;

            var backChannel = new Parameters
            {
                { "foo", "foo" },
                { "bar", "bar" }
            };

            var result = await client.ProcessResponseAsync(url, state, backChannel);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().NotBeNull();
            result.User.Should().NotBeNull();

            var body = handler.Body;

            body.Should().Contain("foo=foo");
            body.Should().Contain("bar=bar");
        }
        public async Task untrusted_identity_token_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", Crypto.UntrustedIdentityToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(Crypto.CreateKey());
            _options.BackchannelHandler         = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().StartWith("Error validating token response: Error validating identity token: Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match 'kid'");
        }
        private async void PrepareClient()
        {
            var redirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().OriginalString;

            // Create options for endpoint discovery
            var options = new OidcClientOptions()
            {
                Authority             = "https://demo.identityserver.io",
                ClientId              = "interactive.confidential",
                ClientSecret          = "secret",
                Scope                 = "openid profile email api offline_access",
                RedirectUri           = redirectUri,
                PostLogoutRedirectUri = redirectUri,
                ResponseMode          = OidcClientOptions.AuthorizeResponseMode.Redirect,
                Flow = OidcClientOptions.AuthenticationFlow.AuthorizationCode
            };

            // Create the client. In production application, this is often created and stored
            // directly in the Application class.
            _oidcClient = new OidcClient(options);

            // Invoke Discovery and prepare a request state, containing the nonce.
            // This is done here to ensure the discovery mecanism is done before
            // the user clicks on the SignIn button. Since the opening of a web window
            // should be done during the handling of a user interaction (here it's the button click),
            // it will be too late to reach the discovery endpoint.
            // Not doing this could trigger popup blockers mechanisms in browsers.
            _loginState = await _oidcClient.PrepareLoginAsync();

            btnSignin.IsEnabled = true;

            resultTxt.Text = "Login URI correct";

            // Same for logout url.
            _logoutUrl           = new Uri(await _oidcClient.PrepareLogoutAsync(new LogoutRequest()));
            btnSignout.IsEnabled = true;

            resultTxt.Text = $"Initialization completed.\nStart={_loginState.StartUrl}\nCallback={_loginState.RedirectUri}\nLogout={_logoutUrl}";
        }
Beispiel #10
0
        public async Task At_hash_policy_should_be_enforced(bool atHashRequired)
        {
            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&nonce={state.Nonce}&code=bar";
            var key     = Crypto.CreateKey();
            var idToken = Crypto.CreateJwt(key, "https://authority", "client",
                                           new Claim("sub", "123"),
                                           new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);
            _options.BackchannelHandler         =
                new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);
            _options.Policy.RequireAccessTokenHash = atHashRequired;

            var result = await client.ProcessResponseAsync(url, state);

            if (atHashRequired)
            {
                result.IsError.Should().BeTrue();
                result.Error.Should().Be("Error validating token response: at_hash is missing.");
            }
            else
            {
                result.IsError.Should().BeFalse();
                result.AccessToken.Should().Be("token");
                result.IdentityToken.Should().NotBeNull();
                result.User.Should().NotBeNull();
            }
        }
        public async Task Untrusted_identity_token_should_fail()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", Crypto.UntrustedIdentityToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(Crypto.CreateKey());
            _options.BackchannelHandler         = new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeTrue();
            result.Error.Should().Contain("invalid_signature");
        }
Beispiel #12
0
        public async Task Sending_authorization_header_should_succeed()
        {
            _options.ClientSecret = "secret";
            _options.TokenClientCredentialStyle = Client.ClientCredentialStyle.AuthorizationHeader;

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&nonce={state.Nonce}&code=bar";
            var key     = Crypto.CreateKey();
            var idToken = Crypto.CreateJwt(key, "https://authority", "client",
                                           new Claim("at_hash", Crypto.HashData("token")),
                                           new Claim("sub", "123"),
                                           new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);

            var backChannelHandler = new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            _options.BackchannelHandler = backChannelHandler;

            var result = await client.ProcessResponseAsync(url, state);

            var request = backChannelHandler.Request;

            request.Headers.Authorization.Should().NotBeNull();
            request.Headers.Authorization.Scheme.Should().Be("Basic");
            request.Headers.Authorization.Parameter.Should()
            .Be(BasicAuthenticationOAuthHeaderValue.EncodeCredential("client", "secret"));
        }
Beispiel #13
0
        public async Task Valid_response_with_missing_signature_should_succeed()
        {
            _options.Policy.RequireIdentityTokenSignature = false;

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&nonce={state.Nonce}&code=bar";
            var key     = Crypto.CreateKey();
            var idToken = Crypto.CreateJwt(null, "https://authority", "client",
                                           new Claim("at_hash", Crypto.HashData("token")),
                                           new Claim("sub", "123"),
                                           new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);
            _options.BackchannelHandler         =
                new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().NotBeNull();
            result.User.Should().NotBeNull();

            result.User.Claims.Count().Should().Be(1);
            result.User.Claims.First().Type.Should().Be("sub");
            result.User.Claims.First().Value.Should().Be("123");
        }
        public async Task Valid_response_should_succeed()
        {
            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var key             = Crypto.CreateKey();
            var frontChannelJwt = Crypto.CreateJwt(key, "https://authority", "client",
                                                   new Claim("sub", "123"),
                                                   new Claim("nonce", state.Nonce),
                                                   new Claim("c_hash", Crypto.HashData("code")));

            var url = $"?state={state.State}&nonce={state.Nonce}&code=code&id_token={frontChannelJwt}";

            var backChannelJwt = Crypto.CreateJwt(key, "https://authority", "client",
                                                  new Claim("at_hash", Crypto.HashData("token")),
                                                  new Claim("sub", "123"),
                                                  new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", backChannelJwt },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);
            _options.BackchannelHandler         = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().NotBeNull();
            result.User.Should().NotBeNull();
            result.TokenResponse.Should().NotBeNull();
        }
Beispiel #15
0
        public async Task Sending_client_credentials_in_body_should_succeed()
        {
            _options.ClientSecret = "secret";
            _options.TokenClientCredentialStyle = Client.ClientCredentialStyle.PostBody;

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&nonce={state.Nonce}&code=bar";
            var key     = Crypto.CreateKey();
            var idToken = Crypto.CreateJwt(key, "https://authority", "client",
                                           new Claim("at_hash", Crypto.HashData("token")),
                                           new Claim("sub", "123"),
                                           new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);

            var backChannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            _options.BackchannelHandler = backChannelHandler;

            var result = await client.ProcessResponseAsync(url, state);

            var fields = QueryHelpers.ParseQuery(backChannelHandler.Body);

            fields["client_id"].First().Should().Be("client");
            fields["client_secret"].First().Should().Be("secret");
        }
Beispiel #16
0
        public async Task No_identity_token_on_token_response_and_no_profile_loading_should_succeed()
        {
            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonConvert.SerializeObject(tokenResponse), HttpStatusCode.OK);

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url    = $"?state={state.State}&code=bar";
            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().BeNull();

            result.User.Should().NotBeNull();
            result.User.Claims.Count().Should().Be(0);
        }
        public async Task Valid_response_without_id_token_should_succeed()
        {
            _options.Scope = "api";
            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url = $"?state={state.State}&nonce={state.Nonce}&code=bar";

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "refresh_token", "refresh_token" }
            };

            _options.BackchannelHandler = new NetworkHandler(JsonSerializer.Serialize(tokenResponse), HttpStatusCode.OK);

            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().BeNull();
            result.User.Identity.IsAuthenticated.Should().BeFalse();
        }
Beispiel #18
0
        private static async Task <string> SignIn()
        {
            // create a redirect URI using an available port on the loopback address.
            const string redirectUri = SampleUrls.ConsoleAppCallback;

            Console.WriteLine("redirect URI: " + redirectUri);

            // create an HttpListener to listen for requests on that redirect URI.
            var oidcRedirectListener = new HttpListener();

            oidcRedirectListener.Prefixes.Add(redirectUri);

            Console.WriteLine("Listening..");
            oidcRedirectListener.Start();

            try
            {
                var options = new OidcClientOptions
                {
                    Authority    = SampleUrls.SecurityTokenService,
                    ClientId     = Clients.ConsoleApp,
                    ClientSecret = Secrets.ConsoleApp,
                    Scope        = $"openid profile {SampleScopes.TestApi}",
                    RedirectUri  = redirectUri
                };

                var            client = new OidcClient(options);
                AuthorizeState state  = await client.PrepareLoginAsync();

                Console.WriteLine($"Start URL: {state.StartUrl}");

                // open system browser to start authentication
                OpenBrowser(state.StartUrl);

                // wait for the authorization response.
                HttpListenerContext oidcRedirectListenerContext = await oidcRedirectListener.GetContextAsync();

                string formData = GetRequestPostData(oidcRedirectListenerContext.Request);

                // Brings the Console to Focus.
                //BringConsoleToFront(); // todo: this failed in macos, seems to be windows-only implementation, investigate, commenting out for now

                // sends an HTTP response to the browser.
                HttpListenerResponse response = oidcRedirectListenerContext.Response;
                string responseString         = $"<html><head><meta http-equiv='refresh' content='10;url={SampleUrls.SecurityTokenService}'></head><body>Please return to the app.</body></html>";
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                response.ContentLength64 = buffer.Length;
                Stream responseOutput = response.OutputStream;
                await responseOutput.WriteAsync(buffer, 0, buffer.Length);

                responseOutput.Close();

                Console.WriteLine($"Form Data: {formData}");

                Console.WriteLine();
                Console.WriteLine("going to process response, press any key to continue...");
                Console.ReadKey();

                LoginResult result = await client.ProcessResponseAsync(formData, state);

                if (result.IsError)
                {
                    Console.WriteLine("\n\nError:\n{0}", result.Error);
                    return(null);
                }

                Console.WriteLine("\n\nClaims:");

                foreach (Claim claim in result.User.Claims)
                {
                    Console.WriteLine("  [{0}]: [{1}]", claim.Type, claim.Value);
                }

                Console.WriteLine();
                Console.WriteLine("Access token:\n\n{0}\n", result.AccessToken);

                if (!string.IsNullOrWhiteSpace(result.RefreshToken))
                {
                    Console.WriteLine("Refresh token:\n\n{0}\n", result.RefreshToken);
                }

                return(result.AccessToken);
            }
            finally
            {
                oidcRedirectListener.Stop();
            }
        }
Beispiel #19
0
        private async Task SignIn()
        {
            // create a redirect URI using the custom redirect uri
            string redirectUri = string.Format(CustomUriScheme + "://callback");

            Console.WriteLine("redirect URI: " + redirectUri);

            var options = new OidcClientOptions
            {
                Authority   = Constants.Authority,
                ClientId    = "winconsole",
                Scope       = "openid profile api1",
                RedirectUri = redirectUri,
            };

            var serilog = new LoggerConfiguration()
                          .MinimumLevel.Verbose()
                          .Enrich.FromLogContext()
                          .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}")
                          .CreateLogger();

            options.LoggerFactory.AddSerilog(serilog);

            var client = new OidcClient(options);
            var state  = await client.PrepareLoginAsync();

            Console.WriteLine($"Start URL: {state.StartUrl}");

            var callbackManager = new CallbackManager(state.State);

            // open system browser to start authentication
            Process.Start(state.StartUrl);

            Console.WriteLine("Running callback manager");
            var response = await callbackManager.RunServer();

            Console.WriteLine($"Response from authorize endpoint: {response}");

            // Brings the Console to Focus.
            BringConsoleToFront();

            var result = await client.ProcessResponseAsync(response, state);

            BringConsoleToFront();

            if (result.IsError)
            {
                Console.WriteLine("\n\nError:\n{0}", result.Error);
            }
            else
            {
                Console.WriteLine("\n\nClaims:");
                foreach (var claim in result.User.Claims)
                {
                    Console.WriteLine("{0}: {1}", claim.Type, claim.Value);
                }

                Console.WriteLine();

                if (!string.IsNullOrEmpty(result.IdentityToken))
                {
                    Console.WriteLine("Identity token:\n{0}", result.IdentityToken);
                }

                if (!string.IsNullOrEmpty(result.AccessToken))
                {
                    Console.WriteLine("Access token:\n{0}", result.AccessToken);
                }

                if (!string.IsNullOrWhiteSpace(result.RefreshToken))
                {
                    Console.WriteLine("Refresh token:\n{0}", result.RefreshToken);
                }
            }
        }
Beispiel #20
0
        static async Task Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            var options = new OidcClientOptions
            {
                Authority   = "https://localhost:5301",
                ClientId    = "test",
                RedirectUri = "http://localhost:4000/oauth",
                Scope       = "openid profile user_role classregisterapi.readwrite identityproviderapi.readwrite homeassignmentsapi.readwrite testingapi.readwrite",
                Flow        = OidcClientOptions.AuthenticationFlow.AuthorizationCode,
                Browser     = new NativeBrowser(),
                RefreshDiscoveryDocumentForLogin = true,
                LoadProfile = false
            };

            options.Policy.Discovery.ValidateIssuerName = false;
            var oidcClient = new OidcClient(options);

            var loginResult = await oidcClient.LoginAsync();

            if (loginResult.IsError)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Sikertelen bejelentkezés.");
                return;
            }

            Console.WriteLine("Sikeres bejelentkezés!");
            Console.WriteLine("1 - Access token kiírása");
            Console.WriteLine("2 - Bérlő kiválasztása");
            while (true)
            {
                Console.Write("Választott lehetőség: ");
                var option = Console.ReadLine();
                if (option == "1")
                {
                    Console.WriteLine("Access token:");
                    Console.WriteLine(loginResult.AccessToken);
                    Console.ReadLine();
                    return;
                }

                if (option == "2")
                {
                    using var client = new HttpClient();
                    var response = await "https://localhost:5301/api/users/me"
                                   .WithOAuthBearerToken(loginResult.AccessToken)
                                   .GetJsonAsync <UserDetailsResponse>();

                    for (int i = 0; i < response.Tenants.Count; i++)
                    {
                        Console.WriteLine($"{i} - {response.Tenants[i].Name}");
                    }

                    Console.Write("Választott bérlő: ");
                    var tenantIndex = int.Parse(Console.ReadLine());
                    var tenantId    = response.Tenants[tenantIndex].Id;

                    var authorizeState = await oidcClient.PrepareLoginAsync();

                    var browser       = new NativeBrowser();
                    var browserResult =
                        await browser.InvokeAsync(new BrowserOptions(authorizeState.StartUrl,
                                                                     authorizeState.RedirectUri));

                    var code = HttpUtility.ParseQueryString(browserResult.Response).Get("code");

                    var result = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
                    {
                        Address      = "https://localhost:5301/connect/token",
                        Code         = code,
                        GrantType    = "authorization_code",
                        ClientId     = "test",
                        RedirectUri  = "http://localhost:4000/oauth",
                        CodeVerifier = authorizeState.CodeVerifier,
                        Parameters   = new Dictionary <string, string>
                        {
                            { "tenant_id", tenantId.ToString() }
                        }
                    });

                    if (result.IsError)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("Hiba történt a bejelentkezéskor.");
                        return;
                    }

                    Console.WriteLine("Sikeres belejentkezés!");
                    Console.WriteLine("Access token:");
                    Console.WriteLine(result.AccessToken);
                    Console.ReadLine();
                    return;
                }

                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Ismeretlen lehetőség.");
                Console.ResetColor();
            }
        }
Beispiel #21
0
        public async Task Valid_response_with_profile_should_succeed()
        {
            _options.LoadProfile = true;

            var client = new OidcClient(_options);
            var state  = await client.PrepareLoginAsync();

            var url     = $"?state={state.State}&nonce={state.Nonce}&code=bar";
            var key     = Crypto.CreateKey();
            var idToken = Crypto.CreateJwt(key, "https://authority", "client",
                                           new Claim("at_hash", Crypto.HashData("token")),
                                           new Claim("sub", "123"),
                                           new Claim("nonce", state.Nonce));

            var tokenResponse = new Dictionary <string, object>
            {
                { "access_token", "token" },
                { "expires_in", 300 },
                { "id_token", idToken },
                { "refresh_token", "refresh_token" }
            };

            var userinfoResponse = new Dictionary <string, object>
            {
                { "sub", "123" },
                { "name", "Dominick" }
            };

            _options.ProviderInformation.KeySet = Crypto.CreateKeySet(key);

            var networkHandler = new NetworkHandler(request =>
            {
                if (request.RequestUri.AbsoluteUri.EndsWith("token"))
                {
                    return(JsonConvert.SerializeObject(tokenResponse));
                }
                else if (request.RequestUri.AbsoluteUri.EndsWith("userinfo"))
                {
                    return(JsonConvert.SerializeObject(userinfoResponse));
                }
                else
                {
                    throw new InvalidOperationException("unknown netowrk request.");
                }
            }, HttpStatusCode.OK);

            _options.BackchannelHandler = networkHandler;

            var result = await client.ProcessResponseAsync(url, state);

            result.IsError.Should().BeFalse();
            result.AccessToken.Should().Be("token");
            result.IdentityToken.Should().NotBeNull();
            result.User.Should().NotBeNull();

            result.User.Claims.Count().Should().Be(2);
            result.User.Claims.First().Type.Should().Be("sub");
            result.User.Claims.First().Value.Should().Be("123");
            result.User.Claims.Skip(1).First().Type.Should().Be("name");
            result.User.Claims.Skip(1).First().Value.Should().Be("Dominick");
        }
        private async void SignIn()
        {
            // create a redirect URI using an available port on the loopback address.
            string redirectUri = string.Format("http://127.0.0.1:7890/");
            Console.WriteLine("redirect URI: " + redirectUri);

            // create an HttpListener to listen for requests on that redirect URI.
            var http = new HttpListener();
            http.Prefixes.Add(redirectUri);
            Console.WriteLine("Listening..");
            http.Start();

            var options = new OidcClientOptions
            {
                Authority = "https://demo.identityserver.io",
                ClientId = "native.hybrid",
                Scope = "openid profile api",
                RedirectUri = redirectUri
            };
                
            //    "native",
            //    "secret",
            //    "openid profile api",
            //    redirectUri)
            //{
            //    UseFormPost = true,
            //    Style = OidcClientOptions.AuthenticationStyle.Hybrid
            //};

            var client = new OidcClient(options);
            var state = await client.PrepareLoginAsync();

            Console.WriteLine($"Start URL: {state.StartUrl}");
            
            // open system browser to start authentication
            Process.Start(state.StartUrl);

            // wait for the authorization response.
            var context = await http.GetContextAsync();

            var formData = GetRequestPostData(context.Request);

            // Brings the Console to Focus.
            BringConsoleToFront();

            // sends an HTTP response to the browser.
            var response = context.Response;
            string responseString = string.Format("<html><head><meta http-equiv='refresh' content='10;url=https://demo.identityserver.io'></head><body>Please return to the app.</body></html>");
            var buffer = Encoding.UTF8.GetBytes(responseString);
            response.ContentLength64 = buffer.Length;
            var responseOutput = response.OutputStream;
            await responseOutput.WriteAsync(buffer, 0, buffer.Length);
            responseOutput.Close();

            Console.WriteLine($"Form Data: {formData}");
            var result = await client.ProcessResponseAsync(formData, state);

            if (result.IsError)
            {
                Console.WriteLine("\n\nError:\n{0}", result.Error);
            }
            else
            {
                Console.WriteLine("\n\nClaims:");
                foreach (var claim in result.User.Claims)
                {
                    Console.WriteLine("{0}: {1}", claim.Type, claim.Value);
                }

                Console.WriteLine();
                Console.WriteLine("Access token:\n{0}", result.AccessToken);

                if (!string.IsNullOrWhiteSpace(result.RefreshToken))
                {
                    Console.WriteLine("Refresh token:\n{0}", result.RefreshToken);
                }
            }

            http.Stop();
        }
Beispiel #23
0
        private async static Task SignInAsync()
        {
            // create a redirect URI using an available port on the loopback address.
            string redirectUri = string.Format("http://127.0.0.1:7890/");

            // create an HttpListener to listen for requests on that redirect URI.
            var settings = new WebListenerSettings();

            settings.UrlPrefixes.Add(redirectUri);
            var http = new WebListener(settings);

            http.Start();
            Console.WriteLine("Listening..");

            var options = new OidcClientOptions
            {
                Authority    = _authority,
                ClientId     = "native.hybrid",
                RedirectUri  = redirectUri,
                Scope        = "openid profile offline_access read api",
                ClientSecret = "secret",
                FilterClaims = true,
                LoadProfile  = true,
                Flow         = OidcClientOptions.AuthenticationFlow.Hybrid
            };

            var serilog = new LoggerConfiguration()
                          .MinimumLevel.Verbose()
                          .Enrich.FromLogContext()
                          .WriteTo.LiterateConsole(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}")
                          .CreateLogger();

            options.LoggerFactory.AddSerilog(serilog);

            var client = new OidcClient(options);
            var state  = await client.PrepareLoginAsync();

            OpenBrowser(state.StartUrl);

            var context = await http.AcceptAsync();

            var formData = GetRequestPostData(context.Request);

            if (formData == null)
            {
                Console.WriteLine("Invalid response");
                return;
            }

            await SendResponseAsync(context.Response);

            var result = await client.ProcessResponseAsync(formData, state);

            options.Policy.ForceIntrospectionForAccessToken = true;
            //-- Test POP generation
            var testPop = client.CreatePopToken(new IdentityModel.OidcClient.Pop.EncodingParameters(options, result.AccessToken)
            {
                Method = "GET"
            }.ToJwtPayload(), result.PopTokenKey).ToSignedB64String();

            Console.WriteLine($"Generated PoP Token: {testPop}");

            //--Test validation...
            var testValidate = await client.ValidatePopToken(testPop, false, "read", "secret");

            Console.WriteLine($"PoP Token Valid: {!testValidate.IsError}");

            //--Test refresh
            var refreshResult = await client.RefreshTokenAsync(result.RefreshToken);

            var refreshValidate = client.CreatePopToken(new IdentityModel.OidcClient.Pop.EncodingParameters(options, refreshResult.AccessToken)
            {
                Method = "GET"
            }.ToJwtPayload(), refreshResult.PopTokenKey).ToSignedB64String();
            var refreshValid = await client.ValidatePopToken(refreshValidate, false, "read", "secret");

            var oldValidate = client.CreatePopToken(new IdentityModel.OidcClient.Pop.EncodingParameters(options, result.AccessToken)
            {
                Method = "GET"
            }.ToJwtPayload(), result.PopTokenKey).ToSignedB64String();
            var oldValid = await client.ValidatePopToken(oldValidate, false, "read", "secret");

            Console.WriteLine($"Generated PoP Token after refresh: {testPop}");
            Console.WriteLine($"PoP Token (using refreshed access token) Valid: {!refreshValid.IsError}");
            Console.WriteLine($"PoP Token (using old access token) Valid: {!oldValid.IsError}"); //Depending on how implemented - this should not work for an old token after the refresh token has been used.

            //--Revoke the tokens.
            var revokeClient = new TokenRevocationClient($"{options.Authority}/connect/revocation", options.ClientId, options.ClientSecret);
            var revokeResult = await revokeClient.RevokeRefreshTokenAsync(refreshResult.RefreshToken);

            Console.WriteLine($"Token revocation succeeded: {!revokeResult.IsError}");

            ShowResult(result);
        }