diff --git a/src/Logto.AspNetCore.Authentication.Tests/LogtoCookieContextManagerTests.cs b/src/Logto.AspNetCore.Authentication.Tests/LogtoCookieContextManagerTests.cs new file mode 100644 index 0000000..a5fc37d --- /dev/null +++ b/src/Logto.AspNetCore.Authentication.Tests/LogtoCookieContextManagerTests.cs @@ -0,0 +1,31 @@ +namespace Logto.AspNetCore.Authentication.Tests; + +public class LogtoCookieContextManagerTests +{ + [Theory] + [InlineData("https://www.example.com/", "https://www.example.com/oidc/token")] + [InlineData("https://www.example.com", "https://www.example.com/oidc/token")] + [InlineData("https://example.com", "https://example.com/oidc/token")] + [InlineData("http://www.example.com", "http://www.example.com/oidc/token")] + [InlineData("https://sub.example.com", "https://sub.example.com/oidc/token")] + [InlineData("https://www.example.com/path/", "https://www.example.com/path/oidc/token")] + public void FetchTokenUriParseTest(string endpoint, string expectedUri) + { + var requestUri = LogtoCookieContextManager.GetOidcTokenRequestUri(endpoint); + Assert.Equal(requestUri.ToString(), expectedUri); + } + + [Fact] + public void FetchTokenUriInvalidFormatTest() + { + Assert.Throws(() => LogtoCookieContextManager.GetOidcTokenRequestUri("https:///example.com//")); + } + + [Fact] + public void FetchTokenUriNullOrEmptyTest() + { + Assert.Throws(() => LogtoCookieContextManager.GetOidcTokenRequestUri(null!)); + Assert.Throws(() => LogtoCookieContextManager.GetOidcTokenRequestUri(string.Empty)); + } + +} \ No newline at end of file diff --git a/src/Logto.AspNetCore.Authentication/LogtoCookieContextManager.cs b/src/Logto.AspNetCore.Authentication/LogtoCookieContextManager.cs index f820042..dcf159d 100644 --- a/src/Logto.AspNetCore.Authentication/LogtoCookieContextManager.cs +++ b/src/Logto.AspNetCore.Authentication/LogtoCookieContextManager.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -78,7 +79,6 @@ public async Task Handle() if (logtoOptions.Resource != null && !await RefreshTokens(true)) { context.RejectPrincipal(); - return; } } @@ -177,7 +177,7 @@ public async Task FetchTokensByRefreshToken(string refreshTo } // TODO: The token endpoint should be read from the discovery endpoint or the OpenID Connect context. - var request = new HttpRequestMessage(HttpMethod.Post, $"{logtoOptions.Endpoint}/oidc/token") + var request = new HttpRequestMessage(HttpMethod.Post, GetOidcTokenRequestUri(logtoOptions.Endpoint)) { Content = new FormUrlEncodedContent(body) }; @@ -191,4 +191,17 @@ public async Task FetchTokensByRefreshToken(string refreshTo PropertyNameCaseInsensitive = true, })!; } + + /// + /// Constructs a URI for the OpenID Connect (OIDC) token request based on the provided endpoint. + /// + /// The base endpoint URL as a string. + /// A object representing the full token request URI. + /// Thrown when the provided endpoint is not a valid URI. + public static Uri GetOidcTokenRequestUri(string endpoint) + { + var baseUri = new Uri(endpoint); + var requestUri = new Uri(baseUri, "oidc/token"); + return requestUri; + } }