Giter Club home page Giter Club logo

Comments (4)

KevinOrtman avatar KevinOrtman commented on August 16, 2024 1

Thank you much for that comment - that had me stumped!

from active-directory-b2c-dotnetcore-webapp.

alobakov avatar alobakov commented on August 16, 2024

Just spent the entire day troubleshooting and debugging this issue.
It boils down to the fact that when SignedOutCallbackPath is left unassigned and uses its default value, the OIDC middleware has no criteria to select the right policy when processing a sign-out callback, and simply picks the first declared one.
As a result, when any policy other than the first declared one is being signed out of, the following method fails to re-hydrate the properties previously sent to (and echoed by) the identity provider in the encrypted "state" parameter, which contains the ultimate PostLogoutRedirectUri.

OpenIdConnectHandler.cs (v1.1.0) :

        protected virtual Task<bool> HandleSignOutCallbackAsync()
        {
            StringValues protectedState;
            if (Request.Query.TryGetValue(OpenIdConnectParameterNames.State, out protectedState))
            {
                var properties = Options.StateDataFormat.Unprotect(protectedState);
                if (!string.IsNullOrEmpty(properties?.RedirectUri))
                {
                    Response.Redirect(properties.RedirectUri);
                    return Task.FromResult(true);
                }
            }

            return Task.FromResult(true);
        }

The reason for the failure is that Options.StateDataFormat.Unprotect() internally uses its own KeyRingBasedDataProtector which is policy-specific, resulting in the following exception being thrown by the latter:

The payload was invalid.

Obviously, it cannot decrypt data previously encrypted by another protector which most certainly used a different encryption key.
Notably, the exception is then silently suppressed in SecureDataFormat.cs for security reasons:

        public TData Unprotect(string protectedText, string purpose)
        {
            try
            {
                if (protectedText == null)
                {
                    return default(TData);
                }

                var protectedData = Base64UrlTextEncoder.Decode(protectedText);
                if (protectedData == null)
                {
                    return default(TData);
                }

                var protector = _protector;
                if (!string.IsNullOrEmpty(purpose))
                {
                    protector = protector.CreateProtector(purpose);
                }

                var userData = protector.Unprotect(protectedData);
                if (userData == null)
                {
                    return default(TData);
                }

                return _serializer.Deserialize(userData);
            }
            catch
            {
                // TODO trace exception, but do not leak other information
                return default(TData);
            }
        }

Therefore, no redirect is sent to the user agent.
So, it seems to work as expected and, as @onovotny pointed out, we just need to give it a hint by specifying distinct per-policy signed-out callback paths.

from active-directory-b2c-dotnetcore-webapp.

nhwilly avatar nhwilly commented on August 16, 2024

Man, oh, man. Thank you. Where do I send the beer? This was making me nuts.

from active-directory-b2c-dotnetcore-webapp.

gsacavdm avatar gsacavdm commented on August 16, 2024

I don't believe this is applicable anymore with the updated 1.1 sample. I'll close the issue. Let me know if this is still and issue and we can reopen/revisit.

from active-directory-b2c-dotnetcore-webapp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.