Skip to content

converting asp.net to asp.net core issue on onredirecttoidentityprovider #5126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
techiebuddhas opened this issue Dec 15, 2018 · 1 comment
Closed
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer

Comments

@techiebuddhas
Copy link

techiebuddhas commented Dec 15, 2018

recently we have migrated our project from asp.net to asp.net core, the project was working fine in asp.net, We have followed the migration document of Microsoft for migrating "asp.net to asp.net core" and modified accordingly, unfortunately, OnRedirectToIdentityProvider method in startup class is not working on challenge call (from the controller). It would be great if someone helps me to figure out where my code is wrong. I have been looping on the same issue for a while. thanks in advance.

StartUp.cs

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
         {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            //Add a strongly-typed options class to DI
            services.Configure<AuthOptions>(Configuration.GetSection("Authentication"));



            services.AddAuthentication(opt => {
                opt.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;

            })
            .AddCookie("MiddleWareCookie")
                .AddOpenIdConnect(options => Configuration.Bind("Authentication", options));

            services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
            {

                options.Authority = Configuration["Authentication:Authority"];
                options.ClientId= Configuration["Authentication:ClientId"];
                options.ClientSecret= Configuration["Authentication:ClientSecret"];



                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // Instead of using the default validation (validating against a single issuer value, as we do in
                    // line of business apps), we inject our own multitenant validation logic
                    ValidateIssuer = false,

                    // If the app is meant to be accessed by entire organizations, add your issuer validation logic here.
                    //IssuerValidator = (issuer, securityToken, validationParameters) => {
                    //    if (myIssuerValidationLogic(issuer)) return issuer;
                    //}
                };

                options.Events = new OpenIdConnectEvents
                {

                    OnRedirectToIdentityProvider = (context) =>
                    {
                        object obj = null;
                        var request = context.Request;

                        if (context.HttpContext.Items.TryGetValue("Authority", out obj))
                        {
                            string authority = obj as string;
                            if (authority != null)
                            {
                                context.ProtocolMessage.IssuerAddress = authority;
                            }
                        }
                        //string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        string appBaseUrl = @"https://localhost:44359/";//UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase);
                        Debug.WriteLine($"appBaseUrl: {appBaseUrl}");
                        context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
                        context.ProtocolMessage.Prompt = "select_account";
                        context.ProtocolMessage.Resource =  Configuration["Authentication:AzureResourceManagerIdentifier"];
                        return Task.FromResult(0);
                    },

                    OnAuthorizationCodeReceived = async (context) =>
                    {
                        var request = context.HttpContext.Request;
                        var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
                        var credential = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret);
                        string tenantId = context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

                        //Comment
                        Debug.WriteLine($"tenantID: {tenantId}");
                        // Revisit
                        string signedInUserUniqueName = context.Principal.FindFirst(ClaimTypes.Name).Value.Split('#')[context.Principal.FindFirst(ClaimTypes.Name).Value.Split('#').Length - 1];
                        //Comment
                        Debug.WriteLine($"tenantID: {signedInUserUniqueName}");

                        var tokenCache = new ADALTokenCache(signedInUserUniqueName);
                        tokenCache.Clear();

                        // revisit
                        AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}", tenantId), tokenCache);
                        // var items = authContext.TokenCache.ReadItems().ToList();

                        // revisit
                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                             context.ProtocolMessage.Code, new Uri(currentUri), credential);

                        //Tell the OIDC middleware we got the tokens, it doesn't need to do anything
                        context.HandleCodeRedemption(result.AccessToken, result.IdToken);

                    },

                    OnTokenValidated = (context) => {
                           string issuer = context.Principal.FindFirst("iss").Value;
                        if (issuer != null)
                        {
                            if (!issuer.StartsWith("https://sts.windows.net/"))
                                throw new SecurityTokenValidationException();
                        }


                        return Task.FromResult(0);

                    },

                    OnTicketReceived = context =>
                    {
                        // If your authentication logic is based on users then add your logic here
                        return Task.CompletedTask;
                    },
                    OnAuthenticationFailed = context =>
                    {
                        context.Response.Redirect("/Error");
                        context.HandleResponse(); // Suppress the exception
                        return Task.CompletedTask;
                    },
                    // If your application needs to do authenticate single users, add your user validation below.
                    //OnTokenValidated = context =>
                    //{
                    //    return myUserValidationLogic(context.Ticket.Principal);
                    //}
                };
            });

            services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Subscription Contoller Method

HttpContext.Items.Add("Authority", string.Format(_authOptions.Authority + "OAuth2/Authorize", _directoryId));

                Dictionary<string, string> dict = new Dictionary<string, string>();
                dict["prompt"] = "select_account";

                var userIdentity = new ClaimsIdentity(User.Claims, "login");

                ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

                await HttpContext.AuthenticateAsync("MiddleWareCookie");
@Eilon Eilon added the area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer label Jan 3, 2019
@Eilon
Copy link
Contributor

Eilon commented Jan 3, 2019

Hi @techiebuddhas , we recommend starting from one of our official samples that handles a similar case:

https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-aspnetcore

If you still have issues after trying to work with that, please let us know by filing a new issue with the specific problem you're having.

@Eilon Eilon closed this as completed Jan 3, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer
Projects
None yet
Development

No branches or pull requests

2 participants