diff --git a/AspNet.Security.OAuth.Providers.sln b/AspNet.Security.OAuth.Providers.sln index 682dba718..e351a91bd 100644 --- a/AspNet.Security.OAuth.Providers.sln +++ b/AspNet.Security.OAuth.Providers.sln @@ -233,8 +233,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\build.yml = .github\workflows\build.yml EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNet.Security.OAuth.Kloudless", "src\AspNet.Security.OAuth.Kloudless\AspNet.Security.OAuth.Kloudless.csproj", "{947E1C60-BCE1-402E-9E5A-6D7094A68DE9}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNet.Security.OAuth.KakaoTalk", "src\AspNet.Security.OAuth.KakaoTalk\AspNet.Security.OAuth.KakaoTalk.csproj", "{1B19314C-9F33-4E71-AF0C-46ED8AB621CE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNet.Security.OAuth.Lichess", "src\AspNet.Security.OAuth.Lichess\AspNet.Security.OAuth.Lichess.csproj", "{26DDE1D4-45D5-4CAA-ACB6-71FECF781B27}" @@ -553,10 +551,6 @@ Global {F8A4A5C4-86D9-4CF2-A2FC-3B46CCC51750}.Debug|Any CPU.Build.0 = Debug|Any CPU {F8A4A5C4-86D9-4CF2-A2FC-3B46CCC51750}.Release|Any CPU.ActiveCfg = Release|Any CPU {F8A4A5C4-86D9-4CF2-A2FC-3B46CCC51750}.Release|Any CPU.Build.0 = Release|Any CPU - {947E1C60-BCE1-402E-9E5A-6D7094A68DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {947E1C60-BCE1-402E-9E5A-6D7094A68DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {947E1C60-BCE1-402E-9E5A-6D7094A68DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {947E1C60-BCE1-402E-9E5A-6D7094A68DE9}.Release|Any CPU.Build.0 = Release|Any CPU {1B19314C-9F33-4E71-AF0C-46ED8AB621CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B19314C-9F33-4E71-AF0C-46ED8AB621CE}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B19314C-9F33-4E71-AF0C-46ED8AB621CE}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -758,7 +752,6 @@ Global {286D1FB0-716C-47CB-A519-22E1D34DFDF7} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} {F8A4A5C4-86D9-4CF2-A2FC-3B46CCC51750} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} {B1792D2A-6D6C-4484-968E-D68DF376BA40} = {3FA3F7B5-5373-4E43-8F45-8EC18249E526} - {947E1C60-BCE1-402E-9E5A-6D7094A68DE9} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} {1B19314C-9F33-4E71-AF0C-46ED8AB621CE} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} {26DDE1D4-45D5-4CAA-ACB6-71FECF781B27} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} {DDF7546B-51C4-46EB-B102-7EE720E8E74F} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D} diff --git a/README.md b/README.md index 4bba74f60..bbb498d6d 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,6 @@ If a provider you're looking for does not exist, consider making a PR to add one | JumpCloud | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.JumpCloud?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.JumpCloud/ "Download AspNet.Security.OAuth.JumpCloud from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.JumpCloud?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.JumpCloud "Download AspNet.Security.OAuth.JumpCloud from MyGet.org") | [Documentation](https://jumpcloud.com/support/sso-with-oidc "JumpCloud developer documentation") | | KakaoTalk | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.KakaoTalk?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.KakaoTalk/ "Download AspNet.Security.OAuth.KakaoTalk from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.KakaoTalk?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.KakaoTalk "Download AspNet.Security.OAuth.KakaoTalk from MyGet.org") | [Documentation](https://developers.kakao.com/docs/latest/en/kakaologin/common "KakaoTalk developer documentation") | | Keycloak | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Keycloak?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Keycloak/ "Download AspNet.Security.OAuth.Keycloak from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Keycloak?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Keycloak "Download AspNet.Security.OAuth.Keycloak from MyGet.org") | [Documentation](https://www.keycloak.org/docs/latest/authorization_services/#_service_overview "Keycloak developer documentation") | -| Kloudless | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Kloudless?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Kloudless/ "Download AspNet.Security.OAuth.Kloudless from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Kloudless?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Kloudless "Download AspNet.Security.OAuth.Kloudless from MyGet.org") | [Documentation](https://developers.kloudless.com/docs/v1/authentication "Kloudless developer documentation") | | KOOK | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Kook?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Kook/ "Download AspNet.Security.OAuth.Kook from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Kook?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Kook "Download AspNet.Security.OAuth.Kook from MyGet.org") | [Documentation](https://developer.kookapp.cn/doc/oauth2 "KOOK developer documentation") | | Kroger | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Kroger?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Kroger/ "Download AspNet.Security.OAuth.Kroger from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Kroger?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Kroger "Download AspNet.Security.OAuth.Kroger from MyGet.org") | [Documentation](https://developer.kroger.com/reference/#section/Authentication "Kroger developer documentation") | | Lichess | [![NuGet](https://buildstats.info/nuget/AspNet.Security.OAuth.Lichess?includePreReleases=false)](https://www.nuget.org/packages/AspNet.Security.OAuth.Lichess/ "Download AspNet.Security.OAuth.Lichess from NuGet.org") | [![MyGet](https://buildstats.info/myget/aspnet-contrib/AspNet.Security.OAuth.Lichess?includePreReleases=true)](https://www.myget.org/feed/aspnet-contrib/package/nuget/AspNet.Security.OAuth.Lichess "Download AspNet.Security.OAuth.Lichess from MyGet.org") | [Documentation](https://lichess.org/api#section/Authentication "Lichess developer documentation") | diff --git a/src/AspNet.Security.OAuth.Kloudless/AspNet.Security.OAuth.Kloudless.csproj b/src/AspNet.Security.OAuth.Kloudless/AspNet.Security.OAuth.Kloudless.csproj deleted file mode 100644 index 5f9fcf5e0..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/AspNet.Security.OAuth.Kloudless.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - - - - ASP.NET Core security middleware enabling Kloudless authentication. - Yann ROBIN - aspnetcore;authentication;kloudless;oauth;security - - - - - - - - diff --git a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationConstants.cs b/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationConstants.cs deleted file mode 100644 index bf70095a9..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationConstants.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) - * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers - * for more information concerning the license and the contributors participating to this project. - */ - -namespace AspNet.Security.OAuth.Kloudless; - -/// -/// Contains constants specific to the . -/// -public static class KloudlessAuthenticationConstants -{ - public static class Claims - { - public const string Account = "urn:kloudless:account"; - public const string Created = "urn:kloudless:created"; - public const string Modified = "urn:kloudless:modified"; - public const string Service = "urn:kloudless:service"; - public const string ServiceName = "urn:kloudless:service_name"; - public const string Admin = "urn:kloudless:admin"; - public const string InternalUse = "urn:kloudless:internal_use"; - public const string Api = "urn:kloudless:api"; - public const string Apis = "urn:kloudless:apis"; - public const string EffectiveScope = "urn:kloudless:effective_scope"; - public const string Type = "urn:kloudless:type"; - public const string Enabled = "urn:kloudless:enabled"; - public const string ObjectDefinitions = "urn:kloudless:object_definitions"; - public const string CustomProperties = "urn:kloudless:custom_properties"; - public const string ProxyConnection = "urn:kloudless:proxy_connection"; - public const string Active = "urn:kloudless:active"; - } - - /// - /// Kloudless API Scopes - /// https://developers.kloudless.com/guides/kb/scopes.html - /// - public static class Scopes - { - /// - /// Use all available services in Kloudless. - /// Default scope - /// - public const string Any = "any"; - - /// - /// Cloud Storage API category - /// - public const string Storage = "storage"; - - /// - /// Calendar API category - /// - public const string Calendar = "calendar"; - - /// - /// Email API category - /// - public const string Email = "email"; - - /// - /// CRM API category - /// - public const string Crm = "crm"; - - /// - /// Messaging API category - /// - public const string Messaging = "messaging"; - - /// - /// ITSM API category - /// - public const string Itsm = "itsm"; - - /// - /// Help Desk API category - /// - public const string HelpDesk = "helpdesk"; - } -} diff --git a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationDefaults.cs b/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationDefaults.cs deleted file mode 100644 index 15b974a91..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationDefaults.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) - * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers - * for more information concerning the license and the contributors participating to this project. - */ - -namespace AspNet.Security.OAuth.Kloudless; - -/// -/// Default values for Kloudless authentication. -/// -public static class KloudlessAuthenticationDefaults -{ - /// - /// Default value for . - /// - public const string AuthenticationScheme = "Kloudless"; - - /// - /// Default value for . - /// - public static readonly string DisplayName = "Kloudless"; - - /// - /// Default value for . - /// - public static readonly string Issuer = "Kloudless"; - - /// - /// Default value for . - /// - public static readonly string CallbackPath = "/signin-kloudless"; - - /// - /// Default value for . - /// - public static readonly string AuthorizationEndpoint = "https://api.kloudless.com/v1/oauth"; - - /// - /// Default value for . - /// - public static readonly string TokenEndpoint = "https://api.kloudless.com/v1/oauth/token"; - - /// - /// Default value for . - /// - public static readonly string UserInformationEndpoint = "https://api.kloudless.com/v1/accounts/"; -} diff --git a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationExtensions.cs b/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationExtensions.cs deleted file mode 100644 index b6ec793f4..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationExtensions.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) - * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers - * for more information concerning the license and the contributors participating to this project. - */ - -using AspNet.Security.OAuth.Kloudless; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// Extension methods to add Kloudless authentication capabilities to an HTTP application pipeline. -/// -public static class KloudlessAuthenticationExtensions -{ - /// - /// Adds to the specified - /// , which enables Kloudless authentication capabilities. - /// - /// The authentication builder. - /// A reference to this instance after the operation has completed. - public static AuthenticationBuilder AddKloudless([NotNull] this AuthenticationBuilder builder) - { - return builder.AddKloudless(KloudlessAuthenticationDefaults.AuthenticationScheme, options => { }); - } - - /// - /// Adds to the specified - /// , which enables Kloudless authentication capabilities. - /// - /// The authentication builder. - /// The delegate used to configure the OpenID 2.0 options. - /// A reference to this instance after the operation has completed. - public static AuthenticationBuilder AddKloudless( - [NotNull] this AuthenticationBuilder builder, - [NotNull] Action configuration) - { - return builder.AddKloudless(KloudlessAuthenticationDefaults.AuthenticationScheme, configuration); - } - - /// - /// Adds to the specified - /// , which enables Kloudless authentication capabilities. - /// - /// The authentication builder. - /// The authentication scheme associated with this instance. - /// The delegate used to configure the Kloudless options. - /// The . - public static AuthenticationBuilder AddKloudless( - [NotNull] this AuthenticationBuilder builder, - [NotNull] string scheme, - [NotNull] Action configuration) - { - return builder.AddKloudless(scheme, KloudlessAuthenticationDefaults.DisplayName, configuration); - } - - /// - /// Adds to the specified - /// , which enables Kloudless authentication capabilities. - /// - /// The authentication builder. - /// The authentication scheme associated with this instance. - /// The optional display name associated with this instance. - /// The delegate used to configure the Kloudless options. - /// The . - public static AuthenticationBuilder AddKloudless( - [NotNull] this AuthenticationBuilder builder, - [NotNull] string scheme, - [CanBeNull] string caption, - [NotNull] Action configuration) - { - return builder.AddOAuth(scheme, caption, configuration); - } -} diff --git a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationHandler.cs b/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationHandler.cs deleted file mode 100644 index 910603543..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationHandler.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) - * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers - * for more information concerning the license and the contributors participating to this project. - */ - -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Text.Encodings.Web; -using System.Text.Json; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace AspNet.Security.OAuth.Kloudless; - -public partial class KloudlessAuthenticationHandler : OAuthHandler -{ - public KloudlessAuthenticationHandler( - [NotNull] IOptionsMonitor options, - [NotNull] ILoggerFactory logger, - [NotNull] UrlEncoder encoder) - : base(options, logger, encoder) - { - } - - protected override async Task CreateTicketAsync( - [NotNull] ClaimsIdentity identity, - [NotNull] AuthenticationProperties properties, - [NotNull] OAuthTokenResponse tokens) - { - using var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); - - using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); - if (!response.IsSuccessStatusCode) - { - await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted); - throw new HttpRequestException("An error occurred while retrieving the user profile."); - } - - using var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted)); - - var principal = new ClaimsPrincipal(identity); - var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement); - - var doesObjectsExist = payload.RootElement.TryGetProperty("objects", out var accounts); - if (!doesObjectsExist) - { - throw new AuthenticationFailureException("Property objects is missing on accounts JSON."); - } - - var hasAtLeastOneAccount = accounts.GetArrayLength() > 0; - if (!hasAtLeastOneAccount) - { - throw new AuthenticationFailureException("Accounts JSON does not contains any account."); - } - - context.RunClaimActions(accounts[0]); - - await Events.CreatingTicket(context); - return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name); - } - - private static partial class Log - { - internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken) - { - UserProfileError( - logger, - response.StatusCode, - response.Headers.ToString(), - await response.Content.ReadAsStringAsync(cancellationToken)); - } - - [LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")] - private static partial void UserProfileError( - ILogger logger, - System.Net.HttpStatusCode status, - string headers, - string body); - } -} diff --git a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationOptions.cs b/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationOptions.cs deleted file mode 100644 index 4232686bc..000000000 --- a/src/AspNet.Security.OAuth.Kloudless/KloudlessAuthenticationOptions.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) - * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers - * for more information concerning the license and the contributors participating to this project. - */ - -using System.Security.Claims; -using static AspNet.Security.OAuth.Kloudless.KloudlessAuthenticationConstants; - -namespace AspNet.Security.OAuth.Kloudless; - -/// -/// Defines a set of options used by . -/// -public class KloudlessAuthenticationOptions : OAuthOptions -{ - public KloudlessAuthenticationOptions() - { - ClaimsIssuer = KloudlessAuthenticationDefaults.Issuer; - CallbackPath = KloudlessAuthenticationDefaults.CallbackPath; - - AuthorizationEndpoint = KloudlessAuthenticationDefaults.AuthorizationEndpoint; - TokenEndpoint = KloudlessAuthenticationDefaults.TokenEndpoint; - UserInformationEndpoint = KloudlessAuthenticationDefaults.UserInformationEndpoint; - - ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id"); - ClaimActions.MapJsonKey(ClaimTypes.Name, "account"); - ClaimActions.MapJsonKey(Claims.Account, "account"); - ClaimActions.MapJsonKey(Claims.Service, "service"); - ClaimActions.MapJsonKey(Claims.InternalUse, "internal_use"); - ClaimActions.MapJsonKey(Claims.Created, "created"); - ClaimActions.MapJsonKey(Claims.Modified, "modified"); - ClaimActions.MapJsonKey(Claims.ServiceName, "service_name"); - ClaimActions.MapJsonKey(Claims.Admin, "admin"); - ClaimActions.MapJsonKey(Claims.Apis, "apis"); - ClaimActions.MapJsonKey(Claims.EffectiveScope, "effective_scope"); - ClaimActions.MapJsonKey(Claims.Api, "api"); - ClaimActions.MapJsonKey(Claims.Type, "type"); - ClaimActions.MapJsonKey(Claims.Enabled, "enabled"); - ClaimActions.MapJsonKey(Claims.ObjectDefinitions, "object_definitions"); - ClaimActions.MapJsonKey(Claims.CustomProperties, "custom_properties"); - ClaimActions.MapJsonKey(Claims.ProxyConnection, "proxy_connection"); - ClaimActions.MapJsonKey(Claims.Active, "active"); - - Scope.Add(Scopes.Any); - } -}