Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

Missing User Claims at the ApiController level

$
0
0

We are porting a MVC app to .NET Core 2.0 running in Service Fabric.

We have a problem in getting the Authentication information back in ApiControllers while in the Controllers it is just fine.

In the  Controllers the IPrincipal user contains the following Claims:

((System.Security.Claims.ClaimsPrincipal) user).Claims.ToList()
Count = 10
    [0]: {aio: Y2NgYMhnbwzUr/yYsOK0R1nEyvkyGeVFa+9uYZvo9cGe44rdRnMA}
    [1]: {http://schemas.microsoft.com/claims/authnmethodsreferences: pwd}
    [2]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname: Administrator}
    [3]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname: MOD}
    [4]: {name: MOD Administrator}
    [5]: {http://schemas.microsoft.com/identity/claims/objectidentifier: 41dd586d-9b31-17f2-9772-2b52f258ae98}
    [6]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: BE_66VwY4Lei3rfK_nOeoguQ24ST6Ui5rlzWtI0cr3A}
    [7]: {http://schemas.microsoft.com/identity/claims/tenantid: 62aca416-37f7-4357-8a0c-26fd874bb37b}
    [8]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: admin@somesite.onmicrosoft.com}
    [9]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn: admin@somesite.onmicrosoft.com}

The controller call returns a View that contains a devexpress dxtree, this contains a url to revive data for the tree, and this call is a call to an ApiController, when the call arrives at the APiController the IPrincipal user contains only those two claims:

   [0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: }
   [1]: {http://schemas.microsoft.com/ws/2008/06/identity/claims/role: }

And we really need the other claims there. Obviously this was working flawlessly in the ASP.NET app. but not (yet) in the Core 2.0.
What are we missing the get this working?

Our code:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IConfigurationRoot>(this.Configuration);
            // Add MVC services to the services container.
            services.AddMvc();

            // Add Authentication services.
            services
                .AddAuthentication(sharedOptions =>
                {
                    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddCookie(options => new CookieAuthenticationOptions
                {
                    ExpireTimeSpan = TimeSpan.FromDays(14),
                    SlidingExpiration = false,
                    Cookie = new CookieBuilder
                    {
                        Name = "qtx"
                    }
                })               
                .AddOpenIdConnect(option =>
                {
                    option.ClientId = Configuration["AzureAd:ClientId"]; ;
                    option.ClientSecret = Configuration["AzureAd:ClientSecret"]; ;
                    option.Authority = $"{Configuration["AzureAd:AadInstance"]}/{Configuration["AzureAd:Tenant"]}";
                    option.SignedOutRedirectUri = Configuration["UrlsEtc:SignedOutRedirectUri"];
                    option.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    option.GetClaimsFromUserInfoEndpoint = false;
                    option.Scope.Add("openid");
                    option.SaveTokens = true;
                    option.ResponseType = "code id_token";
                    option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidateIssuer = false
                    };
                    option.Events = new OpenIdConnectEvents()
                    {
                        OnRemoteFailure = async context =>
                        {
                            context.HandleResponse();
                            context.Response.Redirect("/Home/Error?message=" + context.Failure.Message);
                            return;
                        },
                        OnRedirectToIdentityProvider = async context =>
                        {
                            var uri = context.Request.Path; //to do to get the return uri
                            context.ProtocolMessage.RedirectUri = Configuration["UrlsEtc:RedirectUri"];
                            context.ProtocolMessage.PostLogoutRedirectUri = Configuration["UrlsEtc:SignedOutRedirectUri"];
                            return;
                        },
                        OnTokenValidated = async context =>
                        {
                            return;
                        },
                        OnAuthenticationFailed = async context =>
                        {
                            return;
                        },
                        OnTokenResponseReceived = async context =>
                        {
                            return;
                        },
                        OnTicketReceived = async context =>
                        {
                            return;
                        },
                        OnUserInformationReceived = async context =>
                        {
                            return;
                        },
                        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);

                            var distributedCache = context.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
                            string objectId = context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                            string tenantId = context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                            string signedInUserId = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
                            string signedInUserName = context.Principal.Identity.Name;

                            var adalTokenCache = new ADALTokenCache(signedInUserId, tenantId, objectId, signedInUserName, GetConnectionString(Configuration));

                            //AuthenticationContext authContext = new AuthenticationContext(ConfigSettings.idaAADInstance + tenantId, adalTokenCache);
                            AuthenticationContext authContext = new AuthenticationContext(context.Options.Authority, adalTokenCache);

                            var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                                context.ProtocolMessage.Code, new Uri(currentUri), credential, context.Options.Resource);

                            context.HandleCodeRedemption(result.AccessToken, result.IdToken);

                            //AuthenticationResult result2 = await authContext.AcquireTokenByAuthorizationCodeAsync(
                            //    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigSettings.graphResourceID);

                            if (!_tenantService.TenantExists(Guid.Parse(tenantId)))
                            {
                                context.ProtocolMessage.RedirectUri = Configuration["UrlsEtc:RedirectSignupUri"];
                            }
                            return;
                        },
                        OnMessageReceived = async context =>
                        {
                            return;
                        },
                        OnRedirectToIdentityProviderForSignOut = async context =>
                        {
                            return;
                        },
                        OnRemoteSignOut = async context =>
                        {
                            return;
                        },
                    };
                });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseAuthentication();

            // Add the console logger.
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            // Configure error handling middleware.
            app.UseExceptionHandler("/Home/Error");

            // Add static files to the request pipeline.
            app.UseStaticFiles();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

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

Thanks

  Ben


Viewing all articles
Browse latest Browse all 9386

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>