Closed ben-powley closed 1 year ago
I've also encountered it twice on Umbraco Cloud projects for around 4 different users. I can't reproduce it, though :(
Same exact error and version of the CMS as you.
The weird thing about this is that it only happened for users that were invited via the backoffice and never actually accepted the invite.
That results in an entry in the UmbracoUser table but nothing in the umbracoExternalLoginToken and umbracoExternalLogin ones, so it's looking for data that doesn't even exist in the DB.
Have you tried upgrading to 9.3.x to see if the issue persists?
@RyuLindow Thanks for the suggestion. I upgrade the project to 9.3.1 and tried unlinking my account via the CMS, but got the same error unfortunately.
System.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_umbracoExternalLoginToken_umbracoExternalLogin_id". The conflict occurred in database "zz-Crafted-Umbraco-Demo", table "dbo.umbracoExternalLoginToken", column 'externalLoginId'. The statement has been terminated.
This is what I did to get rid of these users since I could delete them via the backoffice:
Go back to [umbracoUser] and delete the user.
Do note that you should only use this approach for users which never interacted with the backoffice.
I think the bug is caused by an incorrect implementation here: https://github.com/umbraco/Umbraco-CMS/blob/release-9.3.1/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ExternalLoginRepository.cs
See line 245 then 254, in case the tokens to be deleted are not present in the existingTokens
because they have been filtered out by line 245, they will never be added the toDelete
collection, thus will not be deleted.
not 100% sure, but i think line 245 doesn't actually make sense in this context.. We want the list of stored tokens for that user to match the state provided by the token
parameter.. So the need for filtering the tokens based on the LoginProvider
is not so clear here.
Hi Guys,
I just connected umbraco 10.0.1 with identity provider 4 (based on this page: https://our.umbraco.com/documentation/Reference/Security/auto-linking/)
But unlinking a user is giving me an error as well:
Possibly unhandled rejection: {"errorMsg":"Unlinking login provider failed","data":"Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'FOREIGN KEY constraint failed'.\r\n at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)\r\n at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()\r\n at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)\r\n at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()\r\n at Umbraco.Cms.Infrastructure.Persistence.FaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)\r\n at NPoco.Database.ExecuteNonQueryHelper(DbCommand cmd)\r\n at NPoco.Database.Execute(String sql, CommandType commandType, Object[] args)\r\n at Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ExternalLoginRepository.Save(Guid userOrMemberKey, IEnumerable`1 logins)\r\n at Umbraco.Cms.Core.Services.ExternalLoginService.Save(Guid userOrMemberKey, IEnumerable`1 logins)\r\n at Umbraco.Cms.Core.Security.BackOfficeUserStore.UpdateAsync(BackOfficeIdentityUser user, CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Identity.UserManager`1.UpdateUserAsync(TUser user)\r\n at Microsoft.AspNetCore.Identity.UserManager`1.RemoveLoginAsync(TUser user, String loginProvider, String providerKey)\r\n at Umbraco.Cms.Web.BackOffice.Controllers.AuthenticationController.PostUnLinkLogin(UnLinkLoginModel unlinkLoginModel)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at Umbraco.Cms.Web.Common.Middleware.BasicAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Web.BackOffice.Middleware.BackOfficeExternalLoginProviderErrorMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext httpContext, Boolean retry)\r\n at StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in C:\\projects\\dotnet\\src\\MiniProfiler.AspNetCore\\MiniProfilerMiddleware.cs:line 119\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Web.Common.Middleware.PreviewAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestLoggingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)\r\n\r\nHEADERS\r\n=======\r\nAccept: application/json, text/plain, */*\r\nAccept-Encoding: br, gzip, deflate\r\nAccept-Language: nl,en-US;q=0.9,en;q=0.8,nl-NL;q=0.7\r\nCache-Control: no-cache\r\nConnection: close\r\nContent-Length: 94\r\nContent-Type: application/json;charset=UTF-8\r\nCookie: ai_user=wDIZ7|2021-12-07T10:05:30.463Z; _ga=GA1.1.405895752.1647862884; CookieConsent={stamp:%27iHluENcEmMd0K5ZFYpitGqmZDjlxUqjsbOFZFu8V/RmoY/uuKPHmqA==%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cver:1%2Cutc:1647862953213%2Cregion:%27nl%27}; _ga_KPJFDX8S7M=GS1.1.1648323143.5.0.1648323143.0; UMB_UPDCHK=1; ActiveSolution=BeukenhorstAPI%24aae7ab3f-7ca4-4f34-b4fd-07370e6c7bfc; idsrv.session=D1D58BE1BF28EC49677D5A8B6C061B3F; .AspNetCore.Antiforgery.wV2LY6geXm4=CfDJ8JW1a4QJpJpDon2m1AlZPfKwCn8_8M2Z3c6UUPG8ckZR15WTE7M2PYlKgoPF65jukWCmuUhzKpLwLYEWvyCqbKTLPdqeIb-GB99On4MYwqphMY9ISYa-e0B5wz0Al3-GMqaECM8Gbd5NmkOTJpVOabQ; .AspNetCore.Identity.Application=CfDJ8JW1a4QJpJpDon2m1AlZPfJ7VUpsRhmg4VBXxdWXFjzhUEKykQjuC8fKrBCYfXl_9MC2dgg465n4xrVtQE1vDHLr1-9Jxs8AGCslHbXDBmOxWbQaqeIEnpXB4Qu5eMEtTMjua8u84WdVs3pyGGk2hlrK6-noMlne1WpuE_XqNg2TmXIrBQnA2D-C4iZ7WYe3uZCrC2rCDN6LXoyqNnABC5LNQiaYrEsURagyormiNYNF1jFx3czj2FM3LEIZTvU7waU1DXSAtRA-s5h1VWNC62l5AGy_SNLDKxUX29tbP8I5P6stRIEKx5YBDPaWLoJfayK0C8u1FY79USFcLWo9BU38j7dx341O7yJXuSbZwRDwQ0RifnsOynUZ83BVkM7RkJdidsIkK6Pz8B2_6w4xSaWJf9mZ0bCTcQ5Y3wOg70YH2ssryt6CO3XSwO4_Je-UuLeY2Tn1YOR9jNAVWoGqLPTlBQ7-CdRMpDGTGWeDvbBnWQzEnDEbggUIb1ntG0LWsf7onzcY2PJuwEBh33zpsjov0T_o8K8zTe7LRPLWSKf2VMcLf6LAnw8mIKFVugAHjJag-swjTjXORZ-lgm9eRSlc88DZQyhsat5lcpvFVhJ2dGSbtL5a94_m4qii2TEr6ejDo_ktE9EDXPczfIelHXOmoAhlAOnUK5Nb28w3YKisN6qpkIE6T7cnputzPFhOIs0g1BK76T0QOddG8NRCxSfHtU598YhrMS-blU2F96ociaSzzKbPEXRExGhPv4fkyHpvWKFPcbbeXkUTJDTGmoMUmHan0xmUASMExk3PXMAi8_9c7luf_MJf2OrTSxKCprRUVDg54mLgNzjnwmmoNSvo6kNKO09poG-9yLRrmfyThFY5--GKrGZEDZ8fstTL23D66I1P2nuL5-6Gu4DtLQfuysfY7TQuaaLOzj8uW2tvD5VDZ1RZH-8olSXkmWtM5BLUU6Rowdz7lz5j7V55jxotdUlXxzefutW0DW9KCquTaW2h4P5jP-W4Eb8hHPkbk2EjqpwKYDtGN1KE7u7mg35Rg_sl3Pq2i5qumJLG0t-Z8LPjBiij1xpaFYES2l2Zo2ic_aW9t5izSfHXuM8zdJmFGfTU2qFAT_ujvNl0mU8Ua9JQzFUIjQ94r3WndX-FOPERcqj_0ZAcgkowMi7483dzTGLXaUCRRSRaUfAqKxpY0VU-inFHcN07ZyHQC8zuove1ME3fA114i8KC3c_2lVwdHDXh_90HDu-ypLu6ctz8gzf3rTFGL5kzmIDMLkHdQw; XSRF-TOKEN=CfDJ8JW1a4QJpJpDon2m1AlZPfKnqROJrWUaMcJr7hUi0kMYXCzWcZ7oNGA14wJijgObqxEllw4gCjyZWXYjvgyktrUDsde0ONDf_UXFfenJwYB_pN19If_jZEiZ5ZdRq39zpUXofVRoIj-Sv2nueMEUtCtZZNI_56-vq1g8rFJ38MjaYRNoZKtHcmZI4VcsQjm4IQ; UMB-XSRF-V=CfDJ8JW1a4QJpJpDon2m1AlZPfLbrEUJ66gKq6Hb0U1XZHgkd1twc-2xOeHJ2ZG8Kn0747L8Z37sO6pzXqakjqKlAWj8ukVnfZB1jK6tVtJYNosinPD4rIh9mvZ7Hzal6ZvHQq-OGS-TS5tkqHBiViXN9vY; UMB-XSRF-TOKEN=CfDJ8JW1a4QJpJpDon2m1AlZPfL1ZL_QvxGRUwYOEbJIkCFOdt32E7_qYJ-f8FG6iPFZyL7KxYVwDvGTgCmiyuW1zivcPn05rVGF6vuCPqlV9naWXd4FTD8wMWJNjpf_E5roXjqvE6IT8F9CKeVEnnDw-MZwnf-xRArKyuWDZ9cZDlltSrek5Qxd4odxzsrEnTX6_Q; UMB_UCONTEXT=CfDJ8JW1a4QJpJpDon2m1AlZPfIY3RZxe_S6KDLMU-ytWy3AEjG_IHDru_JMy7PQoU757a_qKUbLn2fe8UZ98_QBIG1Y-594IIhFbsevrz5PT8Vf7ZIxKENHXte9MySt0iXgkPu-QNtZiuRMJbUTL-s-bpKzEl5D4XDWe44D9ozYbrRLtif9T2mHOgVVB1B5a5cwd4etG-VY-6jCK9J_-m_OTJkUpYMfPJzeS2icOz9yq9ZD47QvB_7ZYnvClw8QIPDIlpRi8hw4UWn6nBDYcG6geEC49Pzeh_EhxhxTC8i1Qd_zYNpdMxIn2GNLVsf6ZFP_1-us7GofquwXwnI06aRU29Ex7iBukj8oVmzvtC0IhdYZ5GrW6JFcRGn20sJChAowX6ZogACxgINJurR0b4oAVw_awc5Sb7fc1DMGfMksVrOJPXmxkT5k4m6f2fGvttTS6rvcaYS9KTzpp0qkqhRHuv8XjI9HumxETaCJ1AvItN9L2kBWn4JooKnR14HIDfKBG9-GKoZw-dwt2PBfCM5vfd2K9TDSMs2Hon5KbEGC_AfTpqa-2gxACUkujc4P6us1x7mURf7S7786L2kz6If1DKXIYjdhfIhMHGwp8nqDrNWRGorqinKKp38A27_exWhuNEjJeF0b5C1u2G155wxGpYHUeLkdazhMuI5d7qehBuwosruOriKsiIHWP1fO-prhxRCDawowKr7OZEaJk_qa0E9Om-7aBYJIYXt35A7apEdmY7qFoJANC2Xtvh9HITKNuxP5qmooZgsYCqHivBU6B8EVKNmghdlkigS3brXdbs-PQ-5Xq0KV4VOGyW9kegVOhZ42c_dThAE6OZBZtpV_7FSadHf4f8_vKEA90ngdDBy9HvY2pJ4gMFWWyBS3qy60c8ornQr7ZvWlBbLEg2VzdAAidLB6INAdJI7KkYcmfSYF9aefhqxYDTo8pV8giSJC8Sv80Pq84_vhrl6xyE36fDSZMeSdxGaD171Veb0OSzGdqg62drhNZK2stKAVcKpUQLwQcDXyA8Icbfh64L9nhwlNu66qK3h90F4lp5EtsNVwkvgH8ICoxWaTQQxP4sI6iSroC5alYt0X4EUbeTwFiWpe6BLTFc1ziUo27bAH4YlCTsbqGNLMuNALEmwLHdHoTsJ8xpmuMGH8lfelGCiw8hB0LHpiHgXJWDHcDXSyQVRXb2WCYv5ENX7Hmz1XY8P0ClvPnimwtP6-wDjj0JtHThhtGF2y-RixSddAAfk_WDO0P3Tz0wK3oX3alA9zCayMk4SV5NJBY_GUbg5gQjdW-XouKpd5QiTddRkvwFPg8VvxhKS8EcGX0nWezHY4WuRzmhM0-FcewRcfG5_-B-wZKG6IMV7hIAe_KEgmTr6yfq3b1SYBf4TRg41E0skAj1IfAReagqlx2Kve3R4w_yP6JherSTWW_wVjafloqzOa1tS7yYNZReXyR3S1Q8Y_HnXpxWgva4VViI0qatqxW6Q7DBZEUiDjBfVD5ChkxH6TcBFANFWddOqS9rm__5LzeNoQE9ff5cTvi5km-D_Is2Af0KF7xagenri2DC_4Ap4z2-vzwzhDrAR-bLizugNWXyPf7vT7PvC6wcvkZ0P8EEtZJW-4YCMnEugJKmjzkLJl3xhIM1OcuJBkrNfO_uug4BOuwNcVS1Q6M6A6jvtazxHQCWvZRKncoHzTk_UNENGQY3MFKqFK-wRG-ksI77aQffn3vQiuX_6lykzcsIqIf--UMFJPVyVsnYDm9p0JoD2_WkQ_Ky_QvA92q_nf9e1p6jArcEk963TQSS_xwskHLvMjeYHofDmS3iHw6rgiH_L_lTHDIZkZgAgZgCNfzIlobp0d68-tMtc_eRi2AMlebZJBo-Tdt_OMJzgV1nj0SB-WQadbREPgK9bcqleeYKICfgHtL1OpQLuKrmY25ib3QU5YH5jaWHG1l-3ewHXFJajMuQG_whm-oyw3Ajs8Tv1No0sPy70GlNt2x5Qyz_4sdmBpxZJ_ts_TDTahmQS4N7PSvwoc5xIH73_nw82AsZvOC6R5OsUZ7Hcxg3hYWH72J1-PKsqaOzkyhQr4BVCZ5EWJdierm07GelG-yW7q4CYe277wlvqG7hwfOrR-VOwoH1lFP4Cd2PWu__lwIZhW6azxCtMiR166te2-TkHX0FMTTSJ542Agg1yz0ztsslCAYEQhG_u4DAine-4OyWv5oN7L0-smmqLOibiB-1rC-NUlIrVc-tf3Cw9fAvF8Gp_zEF4UfX9oxWKeLIGG2NcOY7UHiFjeZO1eTTowXGFMO60TRfsIFobvFakP_To5IJfMRKcWnCHsv-IHSX1ldcZFuzwtVJNgI3ZzMZCj8QFLi2JCCkDT13t8NjcSet7WUBoSRRu4SxhV-PNxzVbCYzFamAJpwutX\r\nHost: localhost:44396\r\nPragma: no-cache\r\nReferer: https://localhost:44396/umbraco\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36\r\nsec-ch-ua: \".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\"\r\nx-umb-segment: null\r\nsec-ch-ua-mobile: ?0\r\nx-requested-with: XMLHttpRequest\r\nx-umb-xsrf-token: CfDJ8JW1a4QJpJpDon2m1AlZPfL1ZL_QvxGRUwYOEbJIkCFOdt32E7_qYJ-f8FG6iPFZyL7KxYVwDvGTgCmiyuW1zivcPn05rVGF6vuCPqlV9naWXd4FTD8wMWJNjpf_E5roXjqvE6IT8F9CKeVEnnDw-MZwnf-xRArKyuWDZ9cZDlltSrek5Qxd4odxzsrEnTX6_Q\r\nsec-ch-ua-platform: \"Windows\"\r\norigin: https://localhost:44396\r\nsec-fetch-site: same-origin\r\nsec-fetch-mode: cors\r\nsec-fetch-dest: empty\r\n","status":500}
I also noticed that the admin user is unable to delete a user which is linked to an external provider. The "ContentEditor" user is the user which is linked:
There is no "delete" button:
Also, it's not possible to see that the user is linked to an external account.
Hi @ben-powley,
Sorry for the late response 😞
I can't reproduce this on V10.3 ... I'm using GitHub as external authentication provider, but the provider doesn't make any difference in terms of unlinking. Here's a screencast of what I'm seeing:
The process can be repeated over and over without errors; each time I login my account is auto-linked back up to my GitHub account.
My login provider options are entirely standard as per the docs, with the exception of explicitly approving the user when auto-linking is performed (see also https://github.com/umbraco/Umbraco-CMS/issues/12487):
public class GitHubBackOfficeExternalLoginProviderOptions : IConfigureNamedOptions<BackOfficeExternalLoginProviderOptions>
{
public const string SchemeName = "GitHub";
public void Configure(string? name, BackOfficeExternalLoginProviderOptions options)
{
if (name != "Umbraco." + SchemeName)
{
return;
}
Configure(options);
}
public void Configure(BackOfficeExternalLoginProviderOptions options)
{
options.ButtonStyle = "btn-danger";
options.Icon = "fa fa-cloud";
options.AutoLinkOptions = new ExternalSignInAutoLinkOptions(
// must be true for auto-linking to be enabled
autoLinkExternalAccount: true,
// Optionally specify default user group, else
// assign in the OnAutoLinking callback
// (default is editor)
defaultUserGroups: new[] { Constants.Security.EditorGroupAlias },
// Optionally specify the default culture to create
// the user as. If null it will use the default
// culture defined in the web.config, or it can
// be dynamically assigned in the OnAutoLinking
// callback.
defaultCulture: null,
// Optionally you can disable the ability to link/unlink
// manually from within the back office. Set this to false
// if you don't want the user to unlink from this external
// provider.
allowManualLinking: true
)
{
// Optional callback
OnAutoLinking = (autoLinkUser, loginInfo) =>
{
// You can customize the user before it's linked.
// i.e. Modify the user's groups based on the Claims returned
// in the externalLogin info
// see https://github.com/umbraco/Umbraco-CMS/issues/12487
autoLinkUser.IsApproved = true;
},
OnExternalLogin = (user, loginInfo) =>
{
// You can customize the user before it's saved whenever they have
// logged in with the external provider.
// i.e. Sync the user's name based on the Claims returned
// in the externalLogin info
return true; //returns a boolean indicating if sign-in should continue or not.
}
};
// Optionally you can disable the ability for users
// to login with a username/password. If this is set
// to true, it will disable username/password login
// even if there are other external login providers installed.
options.DenyLocalLogin = false;
// Optionally choose to automatically redirect to the
// external login provider so the user doesn't have
// to click the login button. This is
options.AutoRedirectLoginToExternalProvider = false;
}
}
Did you try upgrading to the latest V10?
Hi @ben-powley Since we cannot reproduce this on our end, and we haven't heard back in a while, I am going to go ahead and close this for now.
Feel free to re-open if this is still an issue 😊
Which exact Umbraco version are you using? For example: 9.0.1 - don't just write v9
9.2.0
Bug summary
When trying to unlink an external account via the CMS, I am getting the following error -
The DELETE statement conflicted with the REFERENCE constraint "FK_umbracoExternalLoginToken_umbracoExternalLogin_id". The conflict occurred in database "XX", table "dbo.umbracoExternalLoginToken", column 'externalLoginId'. The statement has been terminated.
It looks like the BackOfficeUserStore RemoveLoginAsync is trying to remove the external login, but is not first removing the external login tokens that exist for that login. The user is supposed to be removed from the umbracoExternalLogin table, but the umbracoExternalLoginToken table contains a reference to the login ID and so is preventing the default and causing an error. The error is only visible in the console too as the front-end breaks when this occurs.
Specifics
No response
Steps to reproduce
Follow the Umbraco autolinking of external accounts documentation, whilst keeping manual linking enabled.
Login to the CMS and go to the view profile section and press the "Un-link your XX account" button.
Check the console for the failed PostUnLinkLogin API call.
Expected result / actual result
The local umbraco account should be unlinked from the external account and the external account login and user tokens should be deleted from their corresponding database tables.