Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Logto.AspNetCore.Authentication/LogtoOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class LogtoOptions
/// <summary>
/// The API resource that your application needs to access.
/// See <a href="https://docs.logto.io/docs/recipes/rbac/">RBAC</a> to learn more about how to use role-based access control (RBAC) to protect API resources.
/// <br/>
/// If <see cref="LogtoParameters.Scopes.Organizations" /> is specified in <see cref="Scopes"/>, this value must not be set.
/// </summary>
public string? Resource { get; set; } = null;
/// <summary>
Expand Down Expand Up @@ -63,6 +65,10 @@ public class LogtoOptions
/// set this value to `true` since they are not included in the ID token.
/// </summary>
public bool GetClaimsFromUserInfoEndpoint { get; set; } = false;
/// <summary>
/// Get if `Scopes` contains `LogtoParameters.Scopes.Organizations`.
/// </summary>
public bool IsOrganizationsScopeRequested => Scopes.Contains(LogtoParameters.Scopes.Organizations);
}

/// <summary>
Expand Down
31 changes: 31 additions & 0 deletions src/Logto.AspNetCore.Authentication/LogtoParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ public static class Scopes
/// Note that when requesting this scope, you must set <see cref="LogtoOptions.GetClaimsFromUserInfoEndpoint"/> to <c>true</c>.
/// </summary>
public const string Identities = "identities";
/// <summary>
/// The scope for user's organization IDs and perform organization token grant per <see href="https://github.com/logto-io/rfcs">RFC 0001</see>.
/// <br/>
/// To learn more about Logto Organizations, see <see href="https://docs.logto.io/docs/recipes/organizations/" />.
/// </summary>
public const string Organizations = "urn:logto:scope:organizations";
/// <summary>
/// Scope for user's organization roles per <see href="https://github.com/logto-io/rfcs">RFC 0001</see>.
/// <br/>
/// To learn more about Logto Organizations, see <see href="https://docs.logto.io/docs/recipes/organizations/" />.
/// </summary>
public const string OrganizationRoles = "urn:logto:scope:organization_roles";
}

/// <summary>
Expand Down Expand Up @@ -114,5 +126,24 @@ public static class Claims
/// The claim name for user's identities.
/// </summary>
public const string Identities = "identities";
/// <summary>
/// The claim name for user's organization IDs.
/// </summary>
public const string Organizations = "organizations";
/// <summary>
/// The claim name for user's organization roles. Each role is in the format of `<organization_id>:<role_name>`.
/// </summary>
public const string OrganizationRoles = "organization_roles";
}

/// <summary>
/// Resources that reserved by Logto, which cannot be defined by users.
/// </summary>
public static class ReservedResource
{
/// <summary>
/// The resource for organization template per <see href="https://github.com/logto-io/rfcs">RFC 0001</see>.
/// </summary>
public const string Organizations = "urn:logto:resource:organizations";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ private static void ConfigureOpenIdConnectOptions(OpenIdConnectOptions options,
}

// Handle resource
if (!string.IsNullOrEmpty(logtoOptions.Resource))
if (logtoOptions.IsOrganizationsScopeRequested) {
if (!string.IsNullOrEmpty(logtoOptions.Resource)) {
throw new ArgumentException($"The {nameof(LogtoOptions.Resource)} must be null when requesting the {LogtoParameters.Scopes.Organizations} scope.");
}

options.Resource = LogtoParameters.ReservedResource.Organizations;
} else if (!string.IsNullOrEmpty(logtoOptions.Resource))
{
options.Resource = logtoOptions.Resource;
}
Expand Down