ASP.Net Core 3.1with AzureAd Authentication generating SameSite Error Chrome - asp.net-core

I am using Azure AD Authentication with ASP.Net Core 3.1 and when I Log In/Out I get a SameSite error in the console from chrome.
cookie associated with a cross-site resource at https://login.microsoftonline.com/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure
I can see in Application>Storage>Cookies i have a .AspNetCore.AzureADCookie with same site showing as SameSite None and a tick against secure.
Having looked through other questions and following code snippets I have seen multiple people report this is issue is fixed and others suggesting to add the following in the appropriate startup sections.
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.None;
});
.AddCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
})
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.None
});
I have tried these options and combinations of these options but the error persists.
Additionally, I tried generating a new project with the built in template in VS2019 NetCore 3.1 with Azure Auth and it results in the same error.
Could someone help with what configuration needed to eliminate this issue?

Related

Microsoft.Identity.Web.UI works locally but not in App Service

I've been trying to add auth to my web app following: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-1-MyOrg
If I run locally with appsettings.Development.json via dotnet run, I can log in using my organization credentials as expected. When I containerize and deploy to my Web App in Azure, I do not get logged in successfully. The url in the browser stays at /signin-oidc and goes to the Error page from the default Razor pages app.
The App Service logs have messages saying .AspNetCore.Correlation.OpenIdConnect.[key?] cookie not found
[Update] The auth flow works on my phone but not on desktop.
Why would the same code work locally but not deployed?
Why isn't the cookie found?
Why does it work on iOS but not Windows?
Try to remove app.UseCookiePolicy(); in startup class.
Take a look here
Or the problem was IdentityServer was still using AddDeveloperSigningCredential
You can add a certificate in your code it will work perfectly
Refer here for more info
tl;dr - Setting the same-site cookie options in the authentication settings fixed this.
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.NonceCookie.SameSite = SameSiteMode.Unspecified;
options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
});
This seems to be because the App Service enforces TLS-only and handles the TLS termination. Because of this, requests to the application are always HTTP even though the browser URL is HTTPS. This causes a number of problems, the first was that the redirect URL never matched since the Identity library uses the request scheme to form the redirect URL. I had "fixed" this by injecting a redirect URL rewrite:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.Events ??= new OpenIdConnectEvents();
options.Events.OnRedirectToIdentityProvider += _fixRedirect;
});
...
private async Task _fixRedirect(RedirectContext context)
{
context.Request.Scheme = "https";
if(!context.ProtocolMessage.RedirectUri.StartsWith("https"))
context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http", "https");
await Task.CompletedTask;
}
However, the correlation cookie also seems to use the same HTTP request so that when the redirect comes back, the HTTPS doesn't match. Relaxing the SameSiteMode explicitly tells the browser(?) to allow the differing schemes. This is why my phone, with a different browser with different cookie policy, worked while desktop did not. Running locally using the dev-certs allowed the schemes to match since the app was terminating the TLS rather than the App Service.
I hooked into the CookiePolicyOptions.OnAppendCookie event to inspect the cookies while debugging to find this out.

Attempting Authentication via Azure AD B2C and Authorization via groups from AAD

So I followed the below examples:
Hosted Blazor Web Assembly AAD B2C: here
Azure Active Directory groups and roles : here
I first implemented Hosted Blazor Web Assembly and got that working fine. Went to implement the Group and Roles parts and began to have issues.
Everything is word for word as in the examples but not sure I merged or setup the Program.cs right in the client. When attempting the call I get a "Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed."
Unfortunately none of my breakpoints work so I figured I would reach out and see if any one has any advice.
This is built from the scaffolding for Blazor.
Here is my program.cs in my client app setup.
builder.Services.AddHttpClient("<Server Project Name>", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("KeeperLife.UI.ServerAPI"));
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("https://<Full path to >/API.Access ");
});
builder.Services.AddScoped<GraphAPIAuthorizationMessageHandler>();
builder.Services.AddHttpClient("GraphAPI",
client => client.BaseAddress = new Uri("https://graph.microsoft.com"))
.AddHttpMessageHandler<GraphAPIAuthorizationMessageHandler>();
builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
CustomUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd",
options.ProviderOptions.Authentication);
//Originally this was "..." but it seemed to break base config so i added the same as above and that worked but then tested with it commented out and it still worked so left it commented out.
//options.ProviderOptions.DefaultAccessTokenScopes.Add("https://<Url to full API PAth>/API.Access");
options.ProviderOptions.AdditionalScopesToConsent.Add(
"https://graph.microsoft.com/Directory.Read.All");
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
CustomUserFactory>();
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("SiteAdmin", policy =>
policy.RequireClaim("group", "<The Object ID of the group>"));
});
Not sure why your breakpoints don't work. But as far as I know, AAD B2C does not provide an Out-of-the-box RBAC functionality.
In Azure AD we can implement it by modifying the "groupMembershipClaims" field in application manifest: "groupMembershipClaims": "SecurityGroup". But it's not available in Azure AD B2C.
There is a workaround. Add a new claim type 'groups' into the custom policy and call the Microsoft Graph to get user's groups. Here is an example for your reference.
Vote this user voice post will be helpful.

Asp Net Core with Identity not working after removing HTTPS

I was trying to remove HTTPS to test some caching features and my authentication stopped working. I read that when using Identity authentication will stop working without HTTP, even a custom authentication cookie with an authentication scheme won't work either.
After I comment these 2 lines my app won't work anymore.
// 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();
The use of HTTPS is not mandatory, the application is to be used on our intranet and I have used Identity just to manage users. What options do I have right now?
even with all this, when I try to login it redirects me back to login page, and this using a custom authentication cookie not indentity.
services.AddAuthentication().AddCookie(AuthenticationSchemes.Production, options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(8);
options.LoginPath = new PathString("/Login");
options.LogoutPath = new PathString("/Logout");
options.Cookie.HttpOnly = true;
options.AccessDeniedPath = new PathString("/AccessDenied");
options.SlidingExpiration = true;
options.Cookie.Name = "NoPaper.Production";
options.ExpireTimeSpan = TimeSpan.FromHours(8);
});
UPDATE
It seems the only solution that worked was to create a new project without https and just copy everything from the other and install nuget packages and it worked.
Please explain more detail about the Authentication not working, is there any error? Try to use F12 developer tools to check it. And please make sure you are not using the ex
As far as I know, when we create dotnet core application via Visual Studio, if we select the Individual User Accounts(using Identity), it will generally force the usage of https for best practice reasons.
In this scenario, to disable HTTPS, we could refer to the following steps:
remove the UseHttpsRedirection from the Startup.cs:
app.UseHsts();
app.UseHttpsRedirection();
Right click the project, and click the Properties, in the Debug tab, unchecked the Enable SSL option. Then, the application will be launched using HTTP requests.
If you are not using the Visual Studio, you could also removing the SSL references in the launchSettings.json file:
Besides, please make sure you are not using the external authentication services in your application. I have created new dotnet core application and use above method to disable HTTPS, and then, I could use Identity to register a new user and login.

Vue JS axios HTTP500 Internal Server

I have create an Asp.Net Core Web API and have checked it is working correctly using postman.
I have downloaded the GitHub Project from this blog: https://paweljw.github.io/2017/09/vue.js-front-end-app-part-3-authentication/
I have modified the url in src/backend/vue-axios/axios.js to my web api url
No matter what I do all I get is:
HTTP500: SERVER ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.
(XHR)OPTIONS - http://localhost:61783/api/token
I have put a break point on the Web API Token method and it is never hit.
Any ideas on how to fix this?
Finally cracked it, it was CORS all along!
services.AddCors(options =>
{
options.AddPolicy("AllowAllHeaders",
corsbuilder =>
{
corsbuilder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:8080");
});
});
The WithOrigins helped
And enabled cors with a policy on the controller
[EnableCors("AllowAllHeaders")]

XSRF-TOKEN not updated when using IISExpress and localhost

.Net Core api layer and .Net Core MVC w/ Angular2 front end. Locally, they are running in different website (localhost:xxx1 and localhost:xxx2) and published, the api is running in a sub directory of the frontend.
I've set up the .Net Core Antiforgery like so:
in the ConfigureServices section:
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
});
in the Configure section:
app.Use(next => context =>
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
return next(context);
});
When i initially launch the sites and browse to the website in Chrome, I do get the 2 Antiforgery tokens (.AspNetCore.Antiforgery.xxxx and the XSRF-TOKEN) and when I make a get/post/etc call I see the x-xsrf-token header is added to the call.
The problem is on each call, the api returns a new XSRF-TOKEN cookie but locally my cookie is not updated, it always contains the original value. When published online, this doesn't happen, the cookie updates every time.
I've tried setting the sites up locally to use localhost.somedomain.com but that didn't work.
Any suggestions as to what I'm doing wrong or how to get it working locally?
The issue on my local machine was that I was running each app in its own IIS Express (localhost:xxx1 and localhost:xxx2).
I ended up setting IIS up to host .net core following this article (https://learn.microsoft.com/en-us/aspnet/core/publishing/iis) and i'm getting the expected result.