C# publish Web Core App to Azure problems with external login (Google Api) - c#

i developed an application with the DotNet Core Web Technology on my computer with an external login with Google. Locally the application works. After publishing the application to the azure, I noticed, that I can not login on azure with my google account. I debugged the app and noticed, that the ExternalLoginAsync function returns null. Therefore I can not login with my external account. Afterwards i looked at the network stream and detected that the signin-google page is requested from google with the parameter "&prompt=none". If i look at the network stream on my local computer, I see that the paramter is "&prompt=consent".
My Configurations looks like that:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddGoogle(google =>
{
google.AccessType = "offline";
google.SaveTokens = true;
google.ClientId = "xxxyy";
google.ClientSecret = "xxyyyytt";
});
Does anyone know, why the external login is not working?
Best regards

Related

What type of ApplicationBuilder should I use in MSAL.NET? I'm using ASP.NET Core Web Api

What I'm trying to achieve is to popup a login browser from MSAL.NET, enter username and password, and used the access token to access Microsoft Graph.
Right now I used PublicClientApplicationBuilder to execute AcquireTokenInteractive to popup the login by MSAL.
I'm using ASP.NET Core Web Api.
The problem is, I'm having issue using PublicClientApplicationBuilder when deployed to IIS. It just stucks and always in Pending state.
Below is my sample code that always in Pending state when deployed to IIS:
var app = PublicClientApplicationBuilder.Create(clientId)
.WithDefaultRedirectUri()
.WithTenantId(tenantId)
.Build();
var result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
And now I read an article from here: https://learn.microsoft.com/en-us/answers/questions/91715/msal-acquiretokeninteractive-code-hangs-infinte-lo.html
To use the ConfidentialClientApplicationBuilder. Now the problem is there is no execute in ConfidentialClientApplicationBuilder to popup login browser from MSAL just like the AcquireTokenInteractive.
There are only AcquireTokenSilent, AcquireTokenByAuthorizationCode, AcquireTokenOnBehalfOf, and AcquireTokenForClient. But all of these don't seem to popup a login browser from MSAL.NET
Below is my sample code:
var confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.Build();
var result = await confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync();
How do I manage to popup a login browser from MSAL by using ConfidentialClientApplicationBuilder?
You should first know about MSAL. You have an asp.net core web app, and you wanna your user to sign in in a popup window and generate access token to call Ms graph api, so you need to refer to this document to integrate azure ad into your web application.
What you mentioned in the question about having issue when deployed to IIS comes from using error method. When you test in your local side with those code, your local computer becomes the sever, it is supposed to work, but if you published the app to IIS, that means the users are hit your app in the client side but the pop up action will appear in the sever side. That's why it always pending.
To sum up here, if you need your users signed in and generate access token with delegate api permission, you should follow the document I post above to realize the feature. But if you can use application permission to generate access token as well, you can then go to use graph SDK with client credential flow to realize it.

Cookie based authentication on multiple 'localhost' Asp.Net Core Sites

Scenario is only an issue on a development machine.
I have multiple different and entirely independent ASP.NET Core 2.2 projects running on my dev machine under "localhost".
Once I successfully authenticate and log in on one project, I can no longer log in to the other projects. I'm assuming it's something to do with the auth cookies.
All projects have the same identical and basic Identity authentication.
services.AddAuthentication();
services.ConfigureApplicationCookie(opt =>
{
opt.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
opt.Cookie.HttpOnly = true;
opt.Cookie.Expiration = TimeSpan.FromHours(4);
opt.ExpireTimeSpan = TimeSpan.FromHours(4);
});
The sign-in call is succeeding:
result = await _signInManager.PasswordSignInAsync(portal.ID, model.Username, model.Password, model.RememberMe, true, loggedInUser);
However, once the user is redirected to the home page, which required authentication, I see the following in the debug output:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed.
... and the user is kicked back to the login page.
Is there a way around this issue?
I would consider running your sites under different domains, and then mapping the domains to localhost (or rather, 127.0.0.1) in your hosts file.
This question explains the technique: Add subdomain to localhost URL
Here is an article which explains the hosts file for different operating systems: https://www.howtogeek.com/howto/27350/beginner-geek-how-to-edit-your-hosts-file/
Problem solved.
services.ConfigureApplicationCookie(opt =>
{
opt.Cookie.Name = "Unique Value Per App";
});
All I have to do is post on SO and the problem solves itself!

Authenticating HttpClient calls from .NET Core on MacOS

My question today is:
How to configure HttpClient so that it can authenticate the call without bothering the user on MacOS?
(.NET Core 2.2 console app running as Launch Agent on MacOS, calling a Web API on IIS with NTLM and Kerberos enabled, over our company's internal network)
Long story:
I have a .NET Core app that uses the following method to call a web api:
var handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
var client = new HttpClient(handler)
{
BaseAddress = new Uri("https://MyWebAPI.MyCompanyName.com/")
};
string result = client.GetAsync("MyEndpointSubURL")
.Result.Content.ReadAsStringAsync().Result;
When I run this on my Windows machine, the app easily connects and gets the result.
However, when I run this on a Mac, I get an exception:
Interop+NetSecurityNative+GssApiException - GSSAPI operation failed with error
The provided name was not a mechanism name. (unknown mech-code 0 for mech unknown).
at Microsoft.Win32.SafeHandles.SafeGssNameHandle.CreatePrincipal(String name)
Any ideas what I need to change to make it work?
We desperately want to avoid bothering the user with prompts (it's meant to be a background syncing service).
Recall, it's a .NET Core 2.2 console app running as Launch Agent on MacOS. The Web API it's calling is an Asp.NET Web API hosted with IIS with NTLM and Kerberos enabled and I only need to get past IIS (web API does not use any authentication/authorization mechanisms by itself). The API is exposed only over our company's internal network, so the user is already logged in to the network.
Try running kinit <username>#<DOMAIN> from the terminal and then running your program again. You may need to configure your krb5.conf file to properly point to the domain controller.
We have "default credentials" working in our system on Mac w/ .NET Core 2.1+ using the same code you show there. Configuring Kerberos through kinit and the conf file is the biggest challenge.
Based on what I can tell, .NET doesn't use the cache produced from running kinit, but this is what configures the principal to be used. .NET's interaction with Kerberos is poorly documented. See https://github.com/dotnet/corefx/issues/30203#issuecomment-395592407
I had a very hard time getting this to work on macOS with .NET Core 2.2.
I followed the online documentation about setting up your krb5.conf, running kinit and klist to make sure I had a valid kerberos ticket.
After all that, kerberos was working with Azure Data Studio, so I knew my setup was okay, but I could not get HttpClient with UseDefaultCredentials = true working. It always failed with the same error:
System.ComponentModel.Win32Exception: GSSAPI operation failed with error - An unsupported mechanism was requested (unknown mech-code 0 for mech unknown).
It did however work on a coworker's machine.
After a lot of digging, we discovered my coworker had .NET Core 2.2.7 installed while I only had 2.2.1. Upgrading my workstation to .NET Core 2.2.8 resolved my issue. Also rolling back our app to use 2.1.13 worked as well.
I hope this helps someone else in the future.
Try this:
With basic auth example.
var url = "https://MyWebAPI.MyCompanyName.com/";
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "Base64Credetials");
using (var response = await httpClient.GetAsync(url))
if (response.IsSuccessStatusCode)
{
var strResponse = await response.Content.ReadAsStringAsync();
MyObject result = JsonConvert.DeserializeObject<MyObject>(strResponse);
if (result != null)
{
//Your code here
}
}
}
I don't think MacOS has a concept of "default authentication" in the same way Windows does. Kerberos and NTLM are both Windows concepts. I suspect on MacOS you will have to use a different authentication scheme (Basic or Bearer) and then retrieve the credentials from somewhere such as the Keychain. IIRC an app can be granted silent read access to the key chain.

Authentication not working inside corporate network

For a company, we are using Xamarin in combination with ADAL.NET to access a web-api which is connected to an Azure Active Directory. When the user logs in, it works fine. However when we are inside the network of the company, we get a 404 response when we get redirected to the corresponding ADFS server.
After some research we came to know that the company uses two different servers to login. One to handle internal requests, and one for traffic outside the network.
So, we are using an emulator to test the app. We changed the hosts file to redirect to the external server which made the login working. (We redirected adfs.******.nl to the IP of the external server.)
Now the question is, how do I fix this inside our app? The company does not want to change their redirects, since it will break more applications like Sharepoint and others.
I read something about this:
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/ADAL-.NET-Q-&-A#why-does-adal-for-windows-store-fails-when-in-corporate-network-while-it-succeeds-otherwise
But that's only for Windows.
Here is how we do the current request:
public static async Task<string> Login()
{
AuthenticationContext authContext = new AuthenticationContext(_authority);
authContext.TokenCache.Clear();
return (await authContext.AcquireTokenAsync(_resourceId, _clientId, _redirect, PlatformParameters)).AccessToken;
}

FileNet Api access rights for asp.net

I have some sort of trouble, but i can't figure out where it can be. I have a search method. It uses filenet api and connects to server using admin credentials.
ClientContext.SetProcessCredentials(new UsernameCredentials(login, password));
var connection = Factory.Connection.GetConnection(storeUri);
var domain = Factory.Domain.GetInstance(connection, null);
var store = Factory.ObjectStore.FetchInstance(domain, storeName, null);
return store;
At target system it works fine, when i run console application. But when i run it at asp.net web site i got
"The requester has insufficient access rights to perform the requested operation." error. Who is requester at this point?
When you're running the application through a console, the user you are logged in as is used i.e. this is you and you probably have admin rights on the machine.
When you run it through IIS, this will depend on which version of IIS you are using. Look at this question for more information. You'll either need to change which user the web site is running under or grant further permissions to the user (or group) that is currently configured.

Categories