Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "cmthomps"

Interesting. I still get the same result. I am building the site on a Mac, could that be the problem?

Just created a dropbox folder and invited you to share.

Sure, where should I send them?

This is what I got.

common-scripts.min.js

This is what it looks like running through a docker container:

Console (Docker)

Network (Docker)

This is the console running through the Visual Studio:

Console (Visual Studio)

Newtork (Visual Studio)

Not sure if it will help, but take a look at my post at:

https://support.aspnetzero.com/QA/Questions/5763

I was having the same issue with GetExternalLoginInfoAsync returning null. Specifically, take a look at the OnTicketReceived event handler I added in AuthConfigurer.cs. What I found was that the GetExternalLoginInfo method was looking for a NameIdentifier claim that is not there for the different openIdConnect vendors I've tried.

Hope it helps.

My project is .NET Core/jQuery. Sorry...

I finally figured this out. Just to be clear, I am replacing the default AspNetZero login experience with the Okta sign-in widget. (See screenshot). In addition to making changes to the login screen itself, I had to make the changes to the AuthConfigurer.cs and the AccountController.cs

The change to the AccountController was basic. Just made a new method to handle the postback from the Okta Widget:

    [HttpPost]
    public ActionResult ExternalLoginOkta(string sessionToken = "")
    {
        string provider = "OpenIdConnect";
        var redirectUrl = Url.Action(
            "ExternalLoginCallback",
            "Account",
            new
            {
                ReturnUrl = "/App",
                authSchema = provider,
                ss = ""
            });

        var properties = new AuthenticationProperties();
        //Note: the sessionToken is created by the Okta Widget and passed into this method.
        properties.Items.Add("sessionToken", sessionToken);
        properties.RedirectUri = redirectUrl;

        var challengeResponse = Challenge(properties, OktaDefaults.MvcAuthenticationScheme);
        return challengeResponse;
    }

I had to do some surgery on the AuthConfigurer.cs class.  I added some event handler to OpenId to handle some apparent data either being in the incorrect place or missing from the data coming back from Okta.

    public static void Configure(IServiceCollection services, IConfiguration configuration)
    {
        var authenticationBuilder = services.AddAuthentication();

        //if (bool.Parse(configuration["Authentication:OpenId:IsEnabled"]))
        //{
        //    authenticationBuilder.AddOpenIdConnect(options =>
        //    {
        //        options.ClientId = configuration["Authentication:OpenId:ClientId"];
        //        options.Authority = configuration["Authentication:OpenId:Authority"];
        //        options.SignedOutRedirectUri = configuration["App:WebSiteRootAddress"] + "Account/Logout";
        //        options.ResponseType = OpenIdConnectResponseType.IdToken;

        //        var clientSecret = configuration["Authentication:OpenId:ClientSecret"];
        //        if (!clientSecret.IsNullOrEmpty())
        //        {
        //            options.ClientSecret = clientSecret;
        //        }
        //    });
        //}

        if (bool.Parse(configuration["Authentication:OpenId:IsEnabled"]))
        {

            authenticationBuilder.AddOpenIdConnect(oidcOptions =>
            {



                oidcOptions.ClientId = configuration["Authentication:OpenId:ClientId"];
                oidcOptions.Authority = configuration["Authentication:OpenId:Authority"];
                oidcOptions.SignedOutRedirectUri = configuration["App:WebSiteRootAddress"] + "Account/Logout";
                oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
                oidcOptions.GetClaimsFromUserInfoEndpoint = true;


                oidcOptions.Scope.Add("openid");
                oidcOptions.Scope.Add("profile");
                oidcOptions.Scope.Add("email");

                var clientSecret = configuration["Authentication:OpenId:ClientSecret"];
                if (!clientSecret.IsNullOrEmpty())
                {
                    oidcOptions.ClientSecret = clientSecret;
                }


                oidcOptions.Events = new OpenIdConnectEvents()
                {
                    //TODO This was the trick to get the Okta widget to work.
                    OnRedirectToIdentityProvider = context =>
                    {
                        // Add Okta sessionToken to provide custom login
                        if (context.Properties.Items.TryGetValue("sessionToken", out var sessionToken))
                        {
                            if (!string.IsNullOrEmpty(sessionToken))
                            {
                                context.ProtocolMessage.SetParameter("sessionToken", sessionToken);
                            }
                        }
                        return Task.CompletedTask;
                    },
                    //TODO This is the only way i can get OpenId to work.
                    OnTicketReceived = context =>
                    {
                        if(!context.Properties.Items.ContainsKey("LoginProvider"))
                        {
                            //For some reason, the LoginProvider isn't being returned when using the Okta Widget
                            context.Properties.Items.Add("LoginProvider", "OpenIdConnect");
                        }
                        // Get the ClaimsIdentity
                        var identity = context.Principal.Identity as ClaimsIdentity;

                        if (identity != null)
                        {
                            // Add the Name ClaimType. This is required if we want User.Identity.Name to actually return something!
                                if (!context.Principal.HasClaim(c => c.Type == ClaimTypes.Name) &&
                                    identity.HasClaim(c => c.Type == "preferred_username"))
                                    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identity.FindFirst("preferred_username").Value));



                            // Check if token names are stored in Properties
                            if (context.Properties.Items.ContainsKey(".TokenNames"))
                            {
                                // Token names a semicolon separated
                                string[] tokenNames = context.Properties.Items[".TokenNames"].Split(';');

                                // Add each token value as Claim
                                foreach (var tokenName in tokenNames)
                                {
                                    // Tokens are stored in a Dictionary with the Key ".Token.<token name>"
                                    string tokenValue = context.Properties.Items[$".Token.{tokenName}"];
                                    identity.AddClaim(new Claim(tokenName, tokenValue));
                                }
                            }

                        }

                        return Task.CompletedTask;
                    }
                };
            });
        }

I'm getting close.

You're saying replace GetUserInfo in the method below with the method in the ticket you mentioned. The new method takes a "token" parameter. Where does that come from?

private async Task<ExternalAuthUserInfo> GetExternalUserInfo(ExternalAuthenticateModel model)
        {
            var userInfo = await _externalAuthManager.GetUserInfo(model.AuthProvider, model.ProviderAccessCode);
            if (userInfo.ProviderKey != model.ProviderKey)
            {
                throw new UserFriendlyException(L("CouldNotValidateExternalUser"));
            }

            return userInfo;
        }

@ismcagdas - Yes, I've configured the application in Okta. I have an okta asp.net core example project that works. And, I have an AspNetZero proof of concept project that I have modified. I'm stuck at the moment.

For the purposes of this proof of concept, I've modified the aspnetzero login page to render the Okta widget and I've modified the the account controller to handle the postback in the same way the okta example works.

Showing 21 to 30 of 59 entries