PrincipalContext has exception when using Impersonation in ASP.NET Web API - c#

I am building an ASP.NET Web API to retrieve Active Directory information using .NET Framework 4.8. The IIS is set to Windows authentication only.
The code works ok on my local machine, but does not work when accessing the API on a client computer.
The issue is from this code:
WindowsIdentity.RunImpersonated(((WindowsIdentity)User.Identity).AccessToken, () => {
var principleContext = new PrincipalContext(ContextType.Domain, null, ConfigHelper.AdRoot);
});
After getting the principalContext, principalContext.ConnectedServer throws an exception
000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection.
If I remove the RunImpersonated part, the code works fine. When I visit the Web API from the server, the impersonation also works.
Please help, thank you!
I guess it might be a double hop issue, but I cannot confirm.

Related

ASP.NET hosted on Centos7 with Windows authentication - GSSAPI: Feature not available

We have ASP.NET backend server running on .NET 5, its hosted on Centos7 and we have some issues with Windows AD authentication.
We have followed this tutorial https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-5.0&tabs=visual-studio#kestrel, meaning that we have added AddAuthentication + AddNegotiate and UseAuthentication to our Startup.cs, host machine - Centos7 is in domain, we have also set the KRB5_KTNAME, it points to the existing keytab file, which we have generated on the domain controller.
When i use command kinit username#DOMAIN.COMPANY.COM and then fill out my password, everything seems to be ok, i also see some ticket, when i invoke klist command.
But for some reason, our ASP.NET server is unable to authenticate me, when i open its url in a browser, fill out my credentials, i get the following error:
2021-06-21 07:51:55.4321|ERROR|Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler|An exception occurred while processing the authentication request. Interop+NetSecurityNative+GssApiException: GSSAPI operation failed with error - Unspecified GSS failure. Minor code may provide more information (Feature not available).
I have completely no idea what this error means and i am unable to google any meaningful results, do you have any ideas?
Thank you!

Error C# Dynamics CRM: The authentication endpoint Username was not found on the configured Secure Token Service

We're facing an error while trying to deploy a WCF webservice in a server. While connecting to Dynamics (CRM on premise) we get this error: The authentication endpoint Username was not found on the configured Secure Token Service
If we test it locally, it's working but if the deploy the webservice in the server, this is the code which performs the login:
Uri serviceUri = new Uri(OrgServiceUri);
proxy = new OrganizationServiceProxy(serviceUri, null, authCredentials, null);
proxy.EnableProxyTypes();
_service = (IOrganizationService)proxy;
Guid userid = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).UserId;
if (userid != Guid.Empty)
{
Console.WriteLine(userid);
return true;
}
else
{
return false;
}
Any guess?
Thank you!!
First, make sure the user you have set up as the service account has Read/Write access to CRM and has a security role assigned that enables it to log into CRM remotely.
Next, make sure the Username endpoint is configured in the ADFS deployment that this CRM org is using:
Log onto the ADFS server and open the ADFS management console. Go to ADFS > Service > Endpoints
You’ll see a list of endpoint URLs here. Find the one for /adfs/services/trust/13/username of type WS-Trust 1.3
Make sure that this endpoint has “Yes” set for both the Enabled and Proxy Enabled settings.
If you have to make a change to this endpoint, after making the change re-start the ADFS server and the CRM server, then try to register again.
Lastly, if the above looks okay, it could be a resolution or routing issue blocking the connection. Make sure that there are external DNS entries for the path to your ADFS server. Also, make sure that your firewall permits external access to the ADFS server. If you are able to, try to use a computer that is outside of your domain to navigate directly to the ADFS server to test its accessibility.
This is a problem with the same error as you, and it has been resolved, you can refer to: The authentication endpoint Username was not found on the configured Secure Token Service
Finally we found it was an issue with ADFS service per-se, networking related, since it wasnt able to connect SSO site. After fixing that, it started to work as a charm.
If you are running ADFS on-prem, the ADFS windows service might be stopped (Because of a power failure / unexpected server restart).
You just need to start it.

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.

Issues using MobileServiceClient and SingleSignOn authentication

So I was just messing around with Azure and decided to look at doing some authentication in a simple Windows 8.1 Xaml based application. I was following the steps outlined in this document.
I Currently setup MobileServices, added an application to the Microsoft Store portal, and also configured the Live Services as outlined in the above link.
Where I am having issues, is when trying to use the Microsoft Account auth SingleSignOn. What's happening is that if I connect using this code:
var client = new MobileServiceClient(MobileAppUrl, MobileAppKey);
var user = await client.LoginAsync(
MobileServiceAuthenticationProvider.MicrosoftAccount, false);
then I get the correct dialog asking for an email and password. When I type it in, it authenticates fine, and works as expected. The problem is when I set the useSingeSignOn flag from false to true, I get the dialog, it asks for permission, and then it gives the following error:
We can't connect to the service you need right now. Check your network connection or try this again later.
Then will then cause an exception when I exit the dialog:
System.IO.FileNotFoundException: The specified protocol is unknown. (Exception from HRESULT: 0x800C000D)":null
I have quadruple checked my azure settings, and they are all correct, as far as I can tell. It's driving me nuts! I have Google and Googled and Googled and found nothing. So then I Binged (doesn't sound as good as Googled), with the same results.
Is there some super secret server setting I possibly missed? Any help/guidance would greatly be appreciated!
Turns out that I just needed to use a different style of signing on. I had to login using the Live SDK, then use the authentication token from that into a different overload of LoginAsync. Now it all works.

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