umbraco / UmbracoIdentityExtensions

Code files & installation that enables easy extensibility points for ASP.Net Identity and the Umbraco back office
MIT License
38 stars 23 forks source link

Login loop #43

Closed adamn9 closed 2 years ago

adamn9 commented 3 years ago

We are currently experiencing multiple users having login loops. T

We are using UmbracoCms.IdentityExtensions version="2.0.0" and UmbracoCms.IdentityExtensions.AzureActiveDirectory version="2.0.0"

App Registration has a email claim configured as ID and we control the access using Enterprise Applicaiton by only letting users login from certain AD group.

When a user is not in that AD group we don't get a successful claim and display an error. However both of those users are in the AD group/App Reg and should work.

Umbraco AD Auth Extensions:


            var adOptions = new OpenIdConnectAuthenticationOptions
            {
                SignInAsAuthenticationType = Constants.Security.BackOfficeExternalAuthenticationType,
                ClientId = clientId,
                Authority = authority,
                RedirectUri = postLoginRedirectUri
            };

            adOptions.ForUmbracoBackOffice(style, icon);            
            adOptions.Caption = caption;
            //Need to set the auth tyep as the issuer path
            adOptions.AuthenticationType = string.Format(
                CultureInfo.InvariantCulture,
                "https://sts.windows.net/{0}/",
                issuerId);
            adOptions.AuthenticationMode = AuthenticationMode.Active;
            adOptions.SetBackOfficeExternalLoginProviderOptions(
                new BackOfficeExternalLoginProviderOptions
                {
                    AutoLinkOptions = new ExternalSignInAutoLinkOptions(
                        // must be true for auto-linking to be enabled
                        autoLinkExternalAccount: true)
                    { 
                        AllowManualLinking = false 
                    }, 

                    // 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.
                    DenyLocalLogin = true,

                    // Optionally choose to automatically redirect to the
                    // external login provider so the user doesn't have
                    // to click the login button. This is
                    AutoRedirectLoginToExternalProvider = true
                });

            app.UseOpenIdConnectAuthentication(adOptions);            

UmbracoAuthTokenServerExtensions:

        {
            var oAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                //generally you wouldn't allow this unless on SSL!
#if DEBUG
                AllowInsecureHttp = true,
#endif
                ApplicationCanDisplayErrors = true, 
                TokenEndpointPath = new PathString("/umbraco/oauth/token"),
                //set as different auth type to not interfere with anyone doing this on the front-end
                AuthenticationType = Umbraco.Core.Constants.Security.BackOfficeTokenAuthenticationType,
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new BackOfficeAuthServerProvider(backofficeAuthServerProviderOptions)
                {
                    OnValidateClientAuthentication = context =>
                    {
                        // Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are
                        // present on the request. If the web application accepts Basic authentication credentials, 
                        // context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web 
                        // application accepts "client_id" and "client_secret" as form encoded POST parameters, 
                        // context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body.
                        // If context.Validated is not called the request will not proceed further. 

                        //** Currently we just accept everything globally
                        context.Validated();
                        return Task.CompletedTask;

                        // Example for checking registered clients:

                        //** Validate that the data is in the request
                        //string clientId;
                        //string clientSecret;
                        //if (context.TryGetFormCredentials(out clientId, out clientSecret) == false)
                        //{
                        //    context.SetError("invalid_client", "Form credentials could not be retrieved.");
                        //    context.Rejected();
                        //    return Task.FromResult(0);
                        //}

                        //var userManager = context.OwinContext.GetUserManager<BackOfficeUserManager>();

                        //** Check if this client id is allowed/registered
                        // - lookup in custom table

                        //** Verify that the client id and client secret match 
                        //if (client != null && userManager.PasswordHasher.VerifyHashedPassword(client.ClientSecretHash, clientSecret) == PasswordVerificationResult.Success)
                        //{
                        //    // Client has been verified.
                        //    context.Validated(clientId);
                        //}
                        //else
                        //{
                        //    // Client could not be validated.
                        //    context.SetError("invalid_client", "Client credentials are invalid.");
                        //    context.Rejected();
                        //}
                    }
                }
            };

            // Token Generation
            app.UseOAuthAuthorizationServer(oAuthServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        }
umbrabot commented 2 years ago

Hiya @adamn9,

Just wanted to let you know that we noticed that this issue got a bit stale and might not be relevant any more.

We will close this issue for now but we're happy to open it up again if you think it's still relevant (for example: it's a feature request that's not yet implemented, or it's a bug that's not yet been fixed).

To open it this issue up again, you can write @umbrabot still relevant in a new comment as the first line. It would be super helpful for us if on the next line you could let us know why you think it's still relevant.

For example:

@umbrabot still relevant This bug can still be reproduced in version x.y.z

This will reopen the issue in the next few hours.

Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face: