diff --git a/src/Authentication/Exceptions/RegisterUserProvisioningException.cs b/src/Authentication/Exceptions/RegisterUserProvisioningException.cs new file mode 100644 index 000000000..9dc55daf6 --- /dev/null +++ b/src/Authentication/Exceptions/RegisterUserProvisioningException.cs @@ -0,0 +1,33 @@ +using System; + +namespace Altinn.Platform.Authentication.Exceptions +{ + /// + /// Thrown when self-identified user provisioning against register fails, so that the + /// OIDC sign-in flow aborts with a clear error instead of continuing with an unpopulated user. + /// + public class RegisterUserProvisioningException : Exception + { + /// + /// Empty constructor. + /// + public RegisterUserProvisioningException() : base() + { + } + + /// + /// With message. + /// + public RegisterUserProvisioningException(string message) : base(message) + { + } + + /// + /// With message and inner exception. + /// + public RegisterUserProvisioningException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/src/Authentication/Services/OidcServerService.cs b/src/Authentication/Services/OidcServerService.cs index 3cf22733b..d0fb0363f 100644 --- a/src/Authentication/Services/OidcServerService.cs +++ b/src/Authentication/Services/OidcServerService.cs @@ -22,6 +22,7 @@ using Altinn.Platform.Authentication.Core.RepositoryInterfaces; using Altinn.Platform.Authentication.Core.Services.Interfaces; using Altinn.Platform.Authentication.Enum; +using Altinn.Platform.Authentication.Exceptions; using Altinn.Platform.Authentication.Helpers; using Altinn.Platform.Authentication.Model; using Altinn.Platform.Authentication.Services.Interfaces; @@ -312,7 +313,22 @@ public async Task HandleUpstreamCallback(UpstreamCallbac // ===== 2) Exchange upstream code for upstream tokens ===== OidcProvider provider = ChooseProviderByKey(upstreamTx.Provider); UserAuthenticationModel userIdenity = await ExtractUserIdentityFromUpstream(input, upstreamTx, provider, cancellationToken); - userIdenity = await IdentifyOrCreateAltinnUser(userIdenity, provider); + + try + { + userIdenity = await IdentifyOrCreateAltinnUser(userIdenity, provider); + } + catch (RegisterUserProvisioningException ex) + { + _logger.LogError(ex, "Self-identified user provisioning via register failed; aborting sign-in."); + return new UpstreamCallbackResult + { + Kind = UpstreamCallbackResultKind.LocalError, + StatusCode = StatusCodes.Status502BadGateway, + LocalErrorMessage = "User provisioning failed. Please try again later." + }; + } + AddLocalScopes(userIdenity); // 3. Create or refresh Altinn session session @@ -1520,11 +1536,6 @@ private async Task IdentifyOrCreateAltinnUser(UserAuthe email: null, CancellationToken.None); - if (provisioned is null) - { - return userAuthenticationModel; - } - userAuthenticationModel.UserID = (int)provisioned.User.Value.UserId.Value; userAuthenticationModel.PartyID = (int)provisioned.PartyId.Value; userAuthenticationModel.PartyUuid = provisioned.Uuid; @@ -1576,11 +1587,6 @@ private async Task IdentifyOrCreateAltinnUser(UserAuthe userAuthenticationModel.Email, CancellationToken.None); - if (provisioned is null) - { - return userAuthenticationModel; - } - userAuthenticationModel.UserID = (int)provisioned.User.Value.UserId.Value; userAuthenticationModel.PartyID = (int)provisioned.PartyId.Value; userAuthenticationModel.PartyUuid = provisioned.Uuid; @@ -1628,7 +1634,7 @@ private async Task IdentifyOrCreateAltinnUser(UserAuthe return userAuthenticationModel; } - private async Task GetOrCreateSelfIdentifiedUserViaRegister( + private async Task GetOrCreateSelfIdentifiedUserViaRegister( SelfIdentifiedUserType selfIdentifiedUserType, string externalIdentity, string userName, @@ -1647,9 +1653,8 @@ private async Task IdentifyOrCreateAltinnUser(UserAuthe if (response is null) { - _logger.LogError( - "Register self-identified provisioning returned no result for externalIdentity {ExternalIdentity}; sign-in cannot complete.", - externalIdentity); + throw new RegisterUserProvisioningException( + $"Register self-identified provisioning returned no result for externalIdentity '{externalIdentity}'; sign-in cannot complete."); } return response;