I made a self-hosted web service in C# (but I don't think the language and framework matter here). The service requires NTLM authentication. When I test the service from Chrome everything works. If I test it from Postman then a certain check fails in the service. In my ApiController I call ((WindowsIdentity)User.Identity).Owner.IsAccountSid() and this method returns false when web calls are made from Postman. The owner's SID is S-1-5-32-544 (Administrators group), which is not an account.
In Postman I did set the username and password, as suggested in another answer. If I change the password, I get 401 Unauthorized, so this tells me I configured Postman correctly. But it doesn't work for me.
Is there a way to make Postman behave more like Chrome (where both direct link and call from JavaScript work correctly)?
Related
I'm attempting to use Postman to "Get User Access Token" with Microsoft Graph API; however, my org recently enabled multi-factor auth and this call is now failing, stating:
"error": "invalid_grant",
"error_description": "AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access...
The Microsoft documentation for MS Graph API using Postman is very well written, but it is missing clear instructions how to pass in this second factor to the request.
The error points to https://login.microsoftonline.com/error?code=50076, but this just gives the same info.
I have the MS authenticator app which gives me this key/second factor; however, I don't know how to add this into the body/headers. I'm trying to find the specific key name for passing in the additional security token (I've tried things like 'token,' 'pcToken,' 'key,' etc.)
.
I was in the same predicament so here is what I did to solve it:
Firstly, I got the information from:
https://github.com/microsoftgraph/microsoftgraph-postman-collections/issues/4
You will need to use the OAuth 2.0 authorisation in Postman. Using the same GET request, go to Authorization -> Change the type to 'OAuth 2.0' then click 'Get New Access Token'.
From there, you can input your own details:
(replace [TenantID] with your own)
Callback URL: The redirect URL you stated in your app authentication.
Auth URL:
https://login.microsoftonline.com/[TenantID]/oauth2/v2.0/authorize
Access Token URL: https://login.microsoftonline.com/[TenantID]/oauth2/v2.0/token
Client ID: You're application's ID.
Client Secret: You're Applications secret that you set under the 'Certificates & secrets' section.
Screenshot
Username Password Authentication is not supported for MFA because MFA requires interaction. But there is no interaction if you need to use Username Password Authentication to sign in.
See Username Password Authentication:
users who need to do MFA won't be able to sign-in (as there is no
interaction)
The answers above do not describe anything related to MFA by-passing via code.
MFA auth you need to use broker authentication where MS Authenticator app behaves as a broker.
If you integrate the proper libraries (ADAL, MSAL) your code will be able to interact with broker properly.
On Android and iOS, brokers enable:
Single Sign On (SSO). Your users won't need to sign-in to each
application
Device identification (by accessing the device
certificate which was created on the device when it was workplace
joined). We use Intune-managed devices for this purpose.
Application identification verification (is it really outlook which
calls me?). The way it works is when an application calls the broker,
it passes its redirect url, and the broker verifies it:
On iOS, the redirect URL is, for instance, ms-word://com.msft.com, the broker
parses and gets the appId (after the //) and verifies it's the same
as the appId of the calling app, which it knows (by the OS).
On Android the redirect URLs have the following form msauth://com.msft.word/.
To enable one of these features, the application developers need to set the UseBroker Boolean to true in the platform parameters. They also need to implement a delegate to react to the broker calling back the application as described in Platform parameters properties specific to brokers on Android and iOS.
Please refer to the MS docs for broker auth examples:
https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/leveraging-brokers-on-Android-and-iOS
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-net-use-brokers-with-xamarin-apps
https://learn.microsoft.com/en-us/azure/active-directory/develop/brokered-auth
I'm trying to hit a web service using RestAssured. I'm struggling with authentication which is actually performed by a third party system. Details are given below:
My web service requires session ID & Cookie in the request header. Otherwise the service call will be failed.
For that I need to fetch Session Id & Cookie after the authentication.
Authentication is done by third party service and it takes the windows credentials for authentication.
When I launch my app URL on browser, say: 'XYZ.com/dim' it will be redirected to authentication service using a URL like:
http://hantweb.DOMAIN.com/authenticate/encdefault.asp?location=XYZ.com/dim
After the authentication it will again be redirected to actual application back.
I tried below code but it says: "401 - Unauthorized: Access is denied due to invalid credentials." even though my credentials are correct.
RestAssured.given().auth().basic("userID", "password").get("http://hantweb.DOMAIN.com/authenticate/encdefault.asp?location=XYZ.com/dim")
I'm confused no idea what I've missed here..
I did some trial and error and finally understood that I need to use .auth().ntlm(userId, password,"","") as the authentication. Here I'm using windows credentials as basic or any other auth type won't work in this case.
This answer can help someone in need.
Is there a way to pass Windows Authentication with postman?
I have added this in header but still 401 Unauthorized.
Authorization: NTLM TkFcYWRtaW46dGVzdA==
As suggested by this link. I've encrypted as Unicode (UTF-16, little-endian) but of no use.
Any Ideas?
I got this working by running Fiddler first.
Run Fiddler (I'm using 4.6.2.3)
Fiddler Menu: Rule -> Automatically Authenticate = true
Postman: Check that Authorization type = No Auth
Browse api.
you can use the the NTLM authorization exist in the Authorization tab same as this photo
I don't think there is a way to do that. But, you are not alone in wanting it...
https://github.com/postmanlabs/postman-app-support/issues/1137
[EDIT]
As of the addition of this edit, Postman has NTLM Authentication in beta in their most recent release.
https://www.getpostman.com/docs/v6/postman/sending_api_requests/authorization
I suggest using insomnia. It's free and you can see the documentation on how to add NTLM Auth here: https://insomnia.rest/documentation/authentication/
NTLM authentication does work with the Chrome plugin version of Postman, as the built-in Chrome NTLM authentication can be used with the plugin. However, plugins are no longer supported by Chrome, so this version can no longer be installed and used.
The current app version of Postman (both the Chrome app and native app versions) does not support NTLM authentication.
This was added to the Postman application in 5.3.0. However, this support was broken in 5.4.1 and remained broken until 7.14.0 per Postman App issue #4355. Updating the app to a newer version of Postman should therefore allow using NTLM authentication.
Note that Postman currently only supports NTLMv1 authentication but not NTLMv2 per Postman App issue #8038.
I will improve upon Hala's answer as it is problematic due to storing credentials in the request and these might get persisted in a shared repository if one is used.
Clear credentials once a request has been successfully issued
One way is to enter the credentials - username, password and domain - make the request and remove them. Subsequent requests will work, probably due to using the same NTLM authentication header, as Postman will add a temporary Authorization header (blurred) that has a value like the following: NTLM some_base64_content
Use environment variables (or better global ones as suggested by SSS) to store sensitive data
Define an environment to use and configure it similar to this:
Use configured environment variables in the request:
You can also change internet options and set Logon to:
Automatic logon with current user name and password
taken from:
https://sysadminspot.com/windows/google-chrome-and-ntlm-auto-logon-using-windows-authentication/
if the website uses https you can add it to Trusted Sites and set it there, otherwise you can add it to local intranet sites and set Custom level... there.
Open internet options:
Click Custom level... and scroll to bottom:
Postman now does NTLM on their desktop apps only.
If you develop your API in C# you can use the following on your Base Controller
#if !DEBUG
[Authorize]
#endif
I have a Silverlight 5 app that runs on a SharePoint 2007 site. The Silverlight app gets a bunch of data from SharePoint lists using the Lists.asmx service. The main site is secured using NTLM security and Silverlight is able to successfully call the web services without having to eplicitly set anything to do with authentication. We extended the SharePoint site to a second domain that uses asp.net FormsBasedAuthentication. On this version of the site, the first web service call fails with a 403 Forbidden response and the exception:
System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
As I understand it, this is a generic message and not the true exception. Well, obviously we need the real exception to have any idea what the problem is. This MSDN page (Creating and Handling Faults in Silverlight) offers two solutions to getting the real exception.
The first is to modify your WCF service to return an alternate HTTP status code. This doesn't work because for one, it is not a WCF service, it's an .asmx web service so I can't add the suggested WCF behavior to modify the status code. Second, it's SharePoint's service so I can't do much to modify it anyway. Could I modify IIS to achieve an equivalent solution somehow?
The second solution is to register an alternative HTTP stack in the Silverlight application. I tried this out and found out the "real" exception was an authentication exception. So I went down dead ends trying to figure out out to get authenticated for about 24 hours only to finally find out that normally, the ASP.NET authentication cookie is passed with the service request, unless you are using the Client HTTP stack. So registering the client HTTP stack allowed me to see real exceptions, but it created its own exception which seems to only be fixed by not using the Client HTTP stack...
I believe have verified with Fiddler that the authentication cookie is being sent when using the default HTTP stack. I don't know if the Lists.asmx service is unable to use it and is giving an authentication error anyway, or if there is some other exception. How can I determine the cause of the "The remote server returned an error: NotFound." exception?
Well, this isn't a good answer to the quesion "How can I determine the cause..." but it's what worked for me. What I did was open up STSSOAP.dll, the assembly containing the Lists service implemention, in reflector. I copied the relevant code to implment my own GetListItems method in my own service. Luckily, the actual Lists.GetListItems method code was minimal and just called other SharePoint methods and even luckier, those methods & members are all declared public so I was able to do this. I then replaced Lists.asmx with my version on the server and attached the debugger to get some info. What I found was my authentication cookie was being used and HttpContext.Current.Session.User.Identity.IsAuthenticated was true. So it knew I was logged in. But I was still getting an authentication error which I could see farther down in SharePoint's code, was converted to a 403.
So I know asp.net considers me authenticated but SharePoint says I don't have permissions. But the service account the app pool is running under is a SP admin so why don't I have permissions? So next I inspected the SPContext.Current.Web.User; SharePoint's current user. It was null! In other words, as far as SharePoint is concerned, I'm still logged in as an anonymous user because I haven't explicitly logged in with a domain user, and an anonymous user doesn't have permissions on the list I'm accessing or most of the rest of the API. The answer by Sean McDonough to this quesion lays it out.
Basically I need to run the involved code with elevated privileges to get the code to run under the asp.net service account that I originally thought it was running under. If using the API, you can use the RunWithElevatedPrivileges delegate. But if you're calling the web services, you can't do that. The few options I could think of were:
Call the services on the base site that uses Windows Authentication. This would require me to embed the credentials in the client-side Silverlight application which is a security threat so I nixed this one.
Implement my own web service to get the data for me.
The web service could access the list using the SharePoint API and
RunWithElevatedPrivileges.
The web service could call the Windows Authentication site's services passing the current credentials or other embedded credentials.
For implementation ease, all I've done so far is the second option under number 2 and it's working. However, it is clunky and I may change to option 1 which I expect will also work.
I'm very novice when it comes to web applications and ASP.
Recently, I've been experimenting with the Microsoft Sync Toolkit to synchronize databases over a OData web service.
The obvious question here is: Once the service is set up and published - so it is open for anyone knowing the URL - how to prevent unauthorized users from accessing this service.
Please note: Basic authentication of forms authentication - as far my little web development knowledge reaches - doesn't seem to be appropriate for this task, as it's not a web page that the client is trying to reach - where the page can display / or re-direct a logon request - it's a service that we are accessing here.
To make things more difficult, for the client-side syncing I'm using a 3rd party library/sync-provider that only accepts a URL for the service. So, there's no way (I think) I can experiment with incorporating login credentials inside a request header etc.
I assume the best bet would be embedding the login credentials inside the URL and use that for the 3rd party library.
Can somebody please direct me how to to set up such thing on the server? I would prefer to have somehow somewhere in the server-side code a place where I can check for the credentials and based upon it to proceed or abort (return 401) the service request.
I could not find any place where to hook such code into the sync service. Although somebody in MSDN suggested to handle the _OnBeginSyncRequest event, there is no way to access the web-request header from within that method.
Is there by-any-chance a global object accessible from everywhere from which I can access the request header? Could anyone please help with this?
And last, I would prefer a plain User / Password string pair. It should not necessarily (or rather not) have anything to do with windows or directory accounts. I would prefer in my code to simple check against plain strings, such if(userStr == "Authenticated user" && passwordStr == "Correct Password").
if you are using SOAP web service, you can use WS-Security usernametoken which adds your user name and password to the request header, otherwise you can add username and password as parameters in your webservice and then simply validate it on the server side. i.e.
instead of
bool SyncData(datatable)
it becomes
bool SyncData(datatable, username, password)
note for web service you will authenticate per call, if you want to do it per session, you need first login with username password, retrieves a token than on each subsequent call your service with the token.
You would also use SSL to secure the channel so username and password aren't transmitted as plain text.