feat(building-block-identity): extend provider-aware identity contracts
This commit is contained in:
parent
1cba08de5b
commit
7d9db8c3d6
@ -8,6 +8,7 @@
|
|||||||
| thalos-service policy contracts | Contracts/Policies | Preserve policy semantics and required fields |
|
| thalos-service policy contracts | Contracts/Policies | Preserve policy semantics and required fields |
|
||||||
| thalos-service policy context contracts | Contracts/Context | Keep field naming stable for compatibility window |
|
| thalos-service policy context contracts | Contracts/Context | Keep field naming stable for compatibility window |
|
||||||
| thalos-bff refresh session contracts | Contracts/Sessions | Candidate for shared capability standardization |
|
| thalos-bff refresh session contracts | Contracts/Sessions | Candidate for shared capability standardization |
|
||||||
|
| provider flow metadata (JWT/Azure/Google) | Contracts/Conventions | Provider metadata stays transport-neutral and additive |
|
||||||
|
|
||||||
## Namespace Strategy
|
## Namespace Strategy
|
||||||
- Current Thalos namespaces are mapped to `BuildingBlock.Identity.Contracts.*`.
|
- Current Thalos namespaces are mapped to `BuildingBlock.Identity.Contracts.*`.
|
||||||
@ -18,3 +19,4 @@
|
|||||||
2. Add compatibility bridge in Thalos consumers.
|
2. Add compatibility bridge in Thalos consumers.
|
||||||
3. Migrate service consumers first, then BFF consumers.
|
3. Migrate service consumers first, then BFF consumers.
|
||||||
4. Deprecate old namespace usage after compatibility window.
|
4. Deprecate old namespace usage after compatibility window.
|
||||||
|
5. Keep provider enum and provider-specific fields additive to avoid breaking consumers.
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
namespace BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Supported identity authentication providers.
|
||||||
|
/// </summary>
|
||||||
|
public enum IdentityAuthProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// AgileWebs-issued internal JWT flow.
|
||||||
|
/// </summary>
|
||||||
|
InternalJwt = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Microsoft Entra ID / Azure AD OAuth/OIDC flow.
|
||||||
|
/// </summary>
|
||||||
|
AzureAd = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Google OAuth/OIDC flow.
|
||||||
|
/// </summary>
|
||||||
|
Google = 2
|
||||||
|
}
|
||||||
@ -6,4 +6,9 @@ namespace BuildingBlock.Identity.Contracts.Grpc;
|
|||||||
/// <param name="SubjectId">Identity subject identifier.</param>
|
/// <param name="SubjectId">Identity subject identifier.</param>
|
||||||
/// <param name="TenantId">Tenant identifier.</param>
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
/// <param name="PermissionCode">Permission code.</param>
|
/// <param name="PermissionCode">Permission code.</param>
|
||||||
public sealed record IdentityPolicyGrpcContract(string SubjectId, string TenantId, string PermissionCode);
|
/// <param name="Provider">Auth provider.</param>
|
||||||
|
public sealed record IdentityPolicyGrpcContract(
|
||||||
|
string SubjectId,
|
||||||
|
string TenantId,
|
||||||
|
string PermissionCode,
|
||||||
|
string Provider = "InternalJwt");
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using BuildingBlock.Identity.Contracts.Abstractions;
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
namespace BuildingBlock.Identity.Contracts.Requests;
|
namespace BuildingBlock.Identity.Contracts.Requests;
|
||||||
|
|
||||||
@ -8,5 +9,10 @@ namespace BuildingBlock.Identity.Contracts.Requests;
|
|||||||
/// <param name="SubjectId">Identity subject identifier.</param>
|
/// <param name="SubjectId">Identity subject identifier.</param>
|
||||||
/// <param name="TenantId">Tenant identifier.</param>
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
/// <param name="PermissionCode">Permission code to evaluate.</param>
|
/// <param name="PermissionCode">Permission code to evaluate.</param>
|
||||||
public sealed record EvaluateIdentityPolicyRequest(string SubjectId, string TenantId, string PermissionCode)
|
/// <param name="Provider">Auth provider used for the request.</param>
|
||||||
|
public sealed record EvaluateIdentityPolicyRequest(
|
||||||
|
string SubjectId,
|
||||||
|
string TenantId,
|
||||||
|
string PermissionCode,
|
||||||
|
IdentityAuthProvider Provider = IdentityAuthProvider.InternalJwt)
|
||||||
: IIdentityCapabilityContract;
|
: IIdentityCapabilityContract;
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
|
namespace BuildingBlock.Identity.Contracts.Requests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests identity provider token exchange for a subject token.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
|
/// <param name="Provider">External identity provider.</param>
|
||||||
|
/// <param name="ExternalToken">Provider-issued token (id/access token).</param>
|
||||||
|
/// <param name="CorrelationId">Correlation identifier.</param>
|
||||||
|
public sealed record ExchangeIdentityProviderTokenRequest(
|
||||||
|
string TenantId,
|
||||||
|
IdentityAuthProvider Provider,
|
||||||
|
string ExternalToken,
|
||||||
|
string CorrelationId = "") : IIdentityCapabilityContract;
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using BuildingBlock.Identity.Contracts.Abstractions;
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
namespace BuildingBlock.Identity.Contracts.Requests;
|
namespace BuildingBlock.Identity.Contracts.Requests;
|
||||||
|
|
||||||
@ -8,5 +9,10 @@ namespace BuildingBlock.Identity.Contracts.Requests;
|
|||||||
/// <param name="SubjectId">Identity subject identifier.</param>
|
/// <param name="SubjectId">Identity subject identifier.</param>
|
||||||
/// <param name="TenantId">Tenant identifier.</param>
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
/// <param name="PermissionCode">Permission code to evaluate.</param>
|
/// <param name="PermissionCode">Permission code to evaluate.</param>
|
||||||
public sealed record IdentityPolicyContextRequest(string SubjectId, string TenantId, string PermissionCode)
|
/// <param name="Provider">Auth provider used for the request.</param>
|
||||||
|
public sealed record IdentityPolicyContextRequest(
|
||||||
|
string SubjectId,
|
||||||
|
string TenantId,
|
||||||
|
string PermissionCode,
|
||||||
|
IdentityAuthProvider Provider = IdentityAuthProvider.InternalJwt)
|
||||||
: IIdentityCapabilityContract;
|
: IIdentityCapabilityContract;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using BuildingBlock.Identity.Contracts.Abstractions;
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
namespace BuildingBlock.Identity.Contracts.Requests;
|
namespace BuildingBlock.Identity.Contracts.Requests;
|
||||||
|
|
||||||
@ -7,4 +8,10 @@ namespace BuildingBlock.Identity.Contracts.Requests;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SubjectId">Identity subject identifier.</param>
|
/// <param name="SubjectId">Identity subject identifier.</param>
|
||||||
/// <param name="TenantId">Tenant identifier.</param>
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
public sealed record IssueIdentityTokenRequest(string SubjectId, string TenantId) : IIdentityCapabilityContract;
|
/// <param name="Provider">Auth provider used for the request.</param>
|
||||||
|
/// <param name="ExternalToken">External provider token when applicable.</param>
|
||||||
|
public sealed record IssueIdentityTokenRequest(
|
||||||
|
string SubjectId,
|
||||||
|
string TenantId,
|
||||||
|
IdentityAuthProvider Provider = IdentityAuthProvider.InternalJwt,
|
||||||
|
string ExternalToken = "") : IIdentityCapabilityContract;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using BuildingBlock.Identity.Contracts.Abstractions;
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
namespace BuildingBlock.Identity.Contracts.Requests;
|
namespace BuildingBlock.Identity.Contracts.Requests;
|
||||||
|
|
||||||
@ -7,5 +8,9 @@ namespace BuildingBlock.Identity.Contracts.Requests;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="RefreshToken">Refresh token value.</param>
|
/// <param name="RefreshToken">Refresh token value.</param>
|
||||||
/// <param name="CorrelationId">Correlation identifier.</param>
|
/// <param name="CorrelationId">Correlation identifier.</param>
|
||||||
public sealed record RefreshIdentitySessionRequest(string RefreshToken, string CorrelationId)
|
/// <param name="Provider">Auth provider used for the request.</param>
|
||||||
|
public sealed record RefreshIdentitySessionRequest(
|
||||||
|
string RefreshToken,
|
||||||
|
string CorrelationId,
|
||||||
|
IdentityAuthProvider Provider = IdentityAuthProvider.InternalJwt)
|
||||||
: IIdentityCapabilityContract;
|
: IIdentityCapabilityContract;
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
using BuildingBlock.Identity.Contracts.Abstractions;
|
||||||
|
using BuildingBlock.Identity.Contracts.Conventions;
|
||||||
|
|
||||||
|
namespace BuildingBlock.Identity.Contracts.Responses;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns token exchange result from an external provider token.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="SubjectId">Resolved identity subject identifier.</param>
|
||||||
|
/// <param name="TenantId">Tenant identifier.</param>
|
||||||
|
/// <param name="Provider">External identity provider.</param>
|
||||||
|
/// <param name="IsAuthenticated">Whether provider token was accepted.</param>
|
||||||
|
public sealed record ExchangeIdentityProviderTokenResponse(
|
||||||
|
string SubjectId,
|
||||||
|
string TenantId,
|
||||||
|
IdentityAuthProvider Provider,
|
||||||
|
bool IsAuthenticated) : IIdentityCapabilityContract;
|
||||||
@ -19,12 +19,33 @@ public class ContractShapeTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void IdentityContracts_WhenInstantiated_ImplementMarkerInterface()
|
public void IdentityContracts_WhenInstantiated_ImplementMarkerInterface()
|
||||||
{
|
{
|
||||||
IIdentityCapabilityContract issueRequest = new IssueIdentityTokenRequest("subject-a", "tenant-a");
|
IIdentityCapabilityContract issueRequest = new IssueIdentityTokenRequest(
|
||||||
|
"subject-a",
|
||||||
|
"tenant-a",
|
||||||
|
IdentityAuthProvider.AzureAd,
|
||||||
|
"external-token");
|
||||||
IIdentityCapabilityContract issueResponse = new IssueIdentityTokenResponse("token-a", 1800);
|
IIdentityCapabilityContract issueResponse = new IssueIdentityTokenResponse("token-a", 1800);
|
||||||
IIdentityCapabilityContract policyRequest = new EvaluateIdentityPolicyRequest("subject-b", "tenant-b", "identity.token.issue");
|
IIdentityCapabilityContract policyRequest = new EvaluateIdentityPolicyRequest(
|
||||||
|
"subject-b",
|
||||||
|
"tenant-b",
|
||||||
|
"identity.token.issue",
|
||||||
|
IdentityAuthProvider.Google);
|
||||||
IIdentityCapabilityContract policyResponse = new EvaluateIdentityPolicyResponse("subject-b", "identity.token.issue", true);
|
IIdentityCapabilityContract policyResponse = new EvaluateIdentityPolicyResponse("subject-b", "identity.token.issue", true);
|
||||||
IIdentityCapabilityContract refreshRequest = new RefreshIdentitySessionRequest("refresh-a", "corr-refresh");
|
IIdentityCapabilityContract refreshRequest = new RefreshIdentitySessionRequest(
|
||||||
|
"refresh-a",
|
||||||
|
"corr-refresh",
|
||||||
|
IdentityAuthProvider.InternalJwt);
|
||||||
IIdentityCapabilityContract refreshResponse = new RefreshIdentitySessionResponse("token-b", 900);
|
IIdentityCapabilityContract refreshResponse = new RefreshIdentitySessionResponse("token-b", 900);
|
||||||
|
IIdentityCapabilityContract exchangeRequest = new ExchangeIdentityProviderTokenRequest(
|
||||||
|
"tenant-c",
|
||||||
|
IdentityAuthProvider.AzureAd,
|
||||||
|
"provider-token",
|
||||||
|
"corr-exchange");
|
||||||
|
IIdentityCapabilityContract exchangeResponse = new ExchangeIdentityProviderTokenResponse(
|
||||||
|
"subject-c",
|
||||||
|
"tenant-c",
|
||||||
|
IdentityAuthProvider.AzureAd,
|
||||||
|
true);
|
||||||
|
|
||||||
Assert.NotNull(issueRequest);
|
Assert.NotNull(issueRequest);
|
||||||
Assert.NotNull(issueResponse);
|
Assert.NotNull(issueResponse);
|
||||||
@ -32,5 +53,20 @@ public class ContractShapeTests
|
|||||||
Assert.NotNull(policyResponse);
|
Assert.NotNull(policyResponse);
|
||||||
Assert.NotNull(refreshRequest);
|
Assert.NotNull(refreshRequest);
|
||||||
Assert.NotNull(refreshResponse);
|
Assert.NotNull(refreshResponse);
|
||||||
|
Assert.NotNull(exchangeRequest);
|
||||||
|
Assert.NotNull(exchangeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IssueIdentityTokenRequest_WhenProviderSpecified_PreservesProviderMetadata()
|
||||||
|
{
|
||||||
|
var request = new IssueIdentityTokenRequest(
|
||||||
|
"subject-1",
|
||||||
|
"tenant-1",
|
||||||
|
IdentityAuthProvider.Google,
|
||||||
|
"google-token");
|
||||||
|
|
||||||
|
Assert.Equal(IdentityAuthProvider.Google, request.Provider);
|
||||||
|
Assert.Equal("google-token", request.ExternalToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user