public void CanRedirectToCorrectEndpoint() { var config = new OpenIdConnectAuthenticationSettings { ClientId = "some-client-id", ClientSecret = "some-client-secret", Scope = "openid some-scope", AuthorizationEndpoint = new Uri("https://id.services.telecom.pt/oic/"), TokenEndpoint = new Uri("https://services.telecom.pt/connect/token_endpoint/access_token"), UserInfoEndpoint = new Uri("https://services.telecom.pt/connect/oic/userinfo/") }; const string signOutRedirectUri = "https://dummy.signout.callback.uri"; var sessionStateStoreMock = new StateSessionStoreMock(); var client = new OpenIdConnectClient(config, sessionStateStoreMock); var response = client.StartSignOut(new AccessTokenResponse { IdToken = "the-id-token" }, signOutRedirectUri); // parameter check // do they all exist? Assert.True(response.Location.Query.Contains("id_token_hint")); Assert.True(response.Location.Query.Contains("post_logout_redirect_uri")); var queryString = TestUtils.GetParsedQueryString(response.Location); // are they filled with the correct values? Assert.Equal(Uri.EscapeUriString(signOutRedirectUri), queryString["post_logout_redirect_uri"]); Assert.Equal(Uri.EscapeUriString("the-id-token"), queryString["id_token_hint"]); }
/// <summary> /// Creates a new OpenIdConnectAuthenticationHandler with the default exchanger (uses HttpClient). /// </summary> /// <param name="openIdSettings"> /// The OpenId client and server settings. /// This includes the client_id and client_secret, as well as the server endpoints. /// </param> /// <param name="sessionSessionStateStore"> /// A session store that will be used to save the state parameters, for CSRF protection. /// </param> public OpenIdConnectClient( OpenIdConnectAuthenticationSettings openIdSettings, ISessionStateStore sessionSessionStateStore) { _openIdSettings = openIdSettings; _sessionSessionStateStore = sessionSessionStateStore; _codeForAccessTokenExchanger = new HttpClientCodeForAccessTokenExchanger(); }
/// <summary> /// Creates a new OpenIdConnectAuthenticationHandler. /// </summary> /// <param name="openIdSettings"> /// The OpenId client and server settings. /// This includes the client_id and client_secret, as well as the server endpoints. /// </param> /// <param name="sessionSessionStateStore"> /// A session store that will be used to save the state parameters, for CSRF protection. /// </param> /// <param name="codeForAccessTokenExchanger"> /// A instance of someone that can exchange authorization codes for access tokens. /// </param> public OpenIdConnectClient( OpenIdConnectAuthenticationSettings openIdSettings, ISessionStateStore sessionSessionStateStore, ICodeForAccessTokenExchanger codeForAccessTokenExchanger) { _openIdSettings = openIdSettings; _sessionSessionStateStore = sessionSessionStateStore; _codeForAccessTokenExchanger = codeForAccessTokenExchanger; }
public void CanRedirectToCorrectEndpoint() { var config = new OpenIdConnectAuthenticationSettings { ClientId = "some-client-id", ClientSecret = "some-client-secret", Scope = "openid some-scope", AuthorizationEndpoint = new Uri("https://id.services.telecom.pt/oic/"), TokenEndpoint = new Uri("https://services.telecom.pt/connect/token_endpoint/access_token"), UserInfoEndpoint = new Uri("https://services.telecom.pt/connect/oic/userinfo/") }; const string signInRedirectUri = "https://dummy.signin.callback.uri"; var sessionStateStoreMock = new StateSessionStoreMock(); var accessTokenExchangerMock = new Mock<ICodeForAccessTokenExchanger>(); var client = new OpenIdConnectClient(config, sessionStateStoreMock, accessTokenExchangerMock.Object); var response = client.StartSignIn(signInRedirectUri); // now we know that we should have a state in the session store, and that the redirect response should have some things: Assert.Equal("https", response.Location.Scheme); Assert.Equal("id.services.telecom.pt", response.Location.Host); // parameter check // do they all exist? Assert.True(response.Location.Query.Contains("state")); Assert.True(response.Location.Query.Contains("client_id")); Assert.True(response.Location.Query.Contains("response_type")); Assert.True(response.Location.Query.Contains("scope")); Assert.True(response.Location.Query.Contains("redirect_uri")); var queryString = TestUtils.GetParsedQueryString(response.Location); // are they filled with the correct values? Assert.Equal(Uri.EscapeUriString((string)sessionStateStoreMock[OpenIdConnectClient.UserLoginStateKey]), queryString["state"]); Assert.Equal(Uri.EscapeUriString(config.ClientId), queryString["client_id"]); Assert.Equal(Uri.EscapeUriString("code"), queryString["response_type"]); Assert.Equal(Uri.EscapeUriString(config.Scope), queryString["scope"]); Assert.Equal(Uri.EscapeUriString(signInRedirectUri), queryString["redirect_uri"]); // ensure that the token endpoint is not called on the start of the flow accessTokenExchangerMock.Verify(e => e.Exchange(It.IsAny<Uri>(), It.IsAny<AccessTokenRequest>()), Times.Never); }
public void RedirectsToRedirectUriImmediatellyWithoutIdToken() { var config = new OpenIdConnectAuthenticationSettings { ClientId = "some-client-id", ClientSecret = "some-client-secret", Scope = "openid some-scope", AuthorizationEndpoint = new Uri("https://id.services.telecom.pt/oic/"), TokenEndpoint = new Uri("https://services.telecom.pt/connect/token_endpoint/access_token"), UserInfoEndpoint = new Uri("https://services.telecom.pt/connect/oic/userinfo/") }; const string signOutRedirectUri = "https://dummy.signout.callback.uri"; var sessionStateStoreMock = new StateSessionStoreMock(); var client = new OpenIdConnectClient(config, sessionStateStoreMock); var response = client.StartSignOut(null, signOutRedirectUri); Assert.Equal(signOutRedirectUri, response.Location.OriginalString); }
/// <summary> /// Creates a new MvcOpenIdConnectClient, given its configuration with the given HttpSessionState store. /// </summary> /// <param name="openIdSettings"> /// The OpenId client and server settings. /// This includes the client_id and client_secret, as well as the server endpoints. /// </param> /// <param name="sessionStateStore">The HttpSessionState to use internally in SystemWebSessionStateStore</param> public MvcOpenIdConnectClient( OpenIdConnectAuthenticationSettings openIdSettings, HttpSessionState sessionStateStore) : base(openIdSettings, new SystemWebSessionStateStore(sessionStateStore)) { }
/// <summary> /// Creates a new MvcOpenIdConnectClient, given its configuration and a custom Session State Store /// </summary> /// <param name="openIdSettings"> /// The OpenId client and server settings. /// This includes the client_id and client_secret, as well as the server endpoints. /// </param> /// <param name="sessionStateStore">The session state store to use internally</param> public MvcOpenIdConnectClient( OpenIdConnectAuthenticationSettings openIdSettings, ISessionStateStore sessionStateStore) : base(openIdSettings, sessionStateStore) { }
public async Task CanCorrectlyCallTokenEndpoint() { var config = new OpenIdConnectAuthenticationSettings { ClientId = "some-client-id", ClientSecret = "some-client-secret", Scope = "openid some-scope", AuthorizationEndpoint = new Uri("https://id.services.telecom.pt/oic/"), TokenEndpoint = new Uri("https://services.telecom.pt/connect/token_endpoint/access_token"), UserInfoEndpoint = new Uri("https://services.telecom.pt/connect/oic/userinfo/") }; const string signInRedirectUri = "https://dummy.signin.callback.uri"; var sessionStateStoreMock = new StateSessionStoreMock(); var accessTokenExchangerMock = new Mock<ICodeForAccessTokenExchanger>(); // mock setup AccessTokenRequest accessTokenRequest = null; accessTokenExchangerMock.Setup(e => e.Exchange(It.IsAny<Uri>(), It.IsAny<AccessTokenRequest>())) .Returns((Uri baseUri, AccessTokenRequest req) => Task.FromResult(new AccessTokenResponse { AccessToken = "some-access-token", ExpiresIn = "3600", IdToken = "the-id-token", RefreshToken = "some-refresh-token", Scope = config.Scope, TokenType = "Bearer" })) .Callback((Uri baseUri, AccessTokenRequest req) => accessTokenRequest = req); var client = new OpenIdConnectClient(config, sessionStateStoreMock, accessTokenExchangerMock.Object); // the response itself is not used, but this will create the state in the session state store client.StartSignIn(signInRedirectUri); // the user is now authenticated and we have an authorization code var accessTokenResponse = await client.CompleteSignIn( "some-code", (string) sessionStateStoreMock[OpenIdConnectClient.UserLoginStateKey], signInRedirectUri); // ensure that the token endpoint was only called once accessTokenExchangerMock.Verify(e => e.Exchange(It.IsAny<Uri>(), It.IsAny<AccessTokenRequest>()), Times.Once); // ensure request values Assert.Equal(config.ClientId, accessTokenRequest.ClientId); Assert.Equal(config.ClientSecret, accessTokenRequest.ClientSecret); Assert.Equal("some-code", accessTokenRequest.Code); Assert.Equal("authorization_code", accessTokenRequest.GrantType); Assert.Equal(signInRedirectUri, accessTokenRequest.RedirectUri); // ensure response values Assert.Equal("some-access-token", accessTokenResponse.AccessToken); Assert.Equal("3600", accessTokenResponse.ExpiresIn); Assert.Equal("the-id-token", accessTokenResponse.IdToken); Assert.Equal("some-refresh-token", accessTokenResponse.RefreshToken); Assert.Equal(config.Scope, accessTokenResponse.Scope); Assert.Equal("Bearer", accessTokenResponse.TokenType); }