IIS app pool application asks for password (basic auth) but neither postman or insomnia can respond - iis

We have an IIS server running a EPICOR ERP system. The ERP system installs IIS application pool, which certain urls are remapped to be handled by the app pool.
Here is what it says about the verification:
For security reasons you should always use https with REST API
REST API supports 2 authentication methods Basic authentication The
username and password are combined into a string separated by a colon
and encoded using Base64. The result is placed into Authorization
header: Authorization: Basic {encoded string} Token authentication The
bearer token can be obtained for the user from token service. See
https://epicorapp2/ERP10.1Test/TokenResource.svc/help (Token
authentication should be enabled). Then access token should be send in
the Authorization header in the following form: Authorization: Bearer
{token string}
The IIS server itself has anonymous authentication for the top level url (and all others are turned off).
My experience in Chrome when I go to the desired URL:
https://epicorapp2/ERP10.1Test/api/help/
is that one gets a pop-up asking for username/password (where the user/passord is for the ERP system, not for the host IIS system).
But I am unable to duplicate this experience either with Postman or Insomnia
(I have tried putting in the username/password in the authorization options for both Postman and Insomnia. I get a 401 authorization error.
Any ideas?

Never got postman to work. But Insomnia works fine as soon as I was able to update the self-sign certificate to DigiCert.

Related

IIS keep prompting Windows Credentials on 401 with IISNode

I'm hosting a web application built with NestJs and React (NodeJs) in an IIS Server with IIS Node. To secure my app, I'm using a system with JWT Token + Refresh Token and Windows Authentication to automatically get the connected user and so generate tokens.
Everything (almost) is working fine, but I have a problem with the Windows Authentification. Each time the JWT Token of my application expired (so the API returns a 401 error page) and only after a refresh of the navigator page, the navigator prompt again the pop up to set windows credentials. The logic use case on this is that one day you're using the webapp, and some days later you want to use the app again, but your token is expired, 401 error, windows credentials is prompting.
If the token expires, and the user simply navigate to another page (so no page refresh with my React SPA) there's no problem, the JWT token is refreshed with the refresh token thanks to the API.
I've already tried some stuff:
Disable Loopback Check
Enable Anonymous and Windows Authentication
Changing some random settings
But I haven't found a solution yet.
My goal is to only have the Windows Credentials display once, when the user visits the page for the first time.
As I'm out of ideas, I'm considering setting a JWT that never expire, but of course it's not a great solution.
Thank you very much for your help!
I ended up using a custom 4xx code to handle my 401. So if my API is sending me a 499 http, I know it mean for my frontend that the session is expired. Hence, I don't have the prompt for Windows Credentials.

Securing a web app against authorization API without revealing credentials

I have a web app MyWebApp.
And two APIs: MyAuthAPI and MyServiceAPI, both RESTful NodeJS. MyAuthAPI uses HashiCorp Vault as a token store with OAuth2.
MyServiceAPI has CRUD operations available to authenticated clients.
There is no human login required (or desired) on MyWebApp. Any human can access MyWebApp through a browser and run the service.
At present, this is the (very insecure) flow:
MyWebApp sends clientid and clientsecret to MyAuthAPI to retrieve token. This token is then used for communicating with MyServiceAPI.
The obvious downside is that anyone can capture the clientid and clientsecret by simply looking in developer tools in a web browser. They could then use those to authenticate with MyAuthAPI, generate their own token, and make calls to MyServiceAPI without MyWebApp being involved.
So how do I best secure the entire application so that MyWebApp is safely and robustly authenticated without revealing the credentials?
Thanks.
ETA:
I want to be able to authenticate MyWebApp with MyAuthAPI and then use the generated token to connect to MyServiceAPI. But I don't want it to be possible that anyone can intercept those credentials - currently they can be see in the request header as "Authorization: Basic "
The MyServiceAPI endpoints must be secured so that only authenticated clients are able to access them. But when that client (MyWebApp) is a public website, how do I authenticate without making the credentials visible?
ETA2:
https://mywebapp.com is MyWebApp which is a React application.
https://myauthapi.com hosts MyAuthAPI
https://myserviceapi.com hosts MyServiceAPI
When I load mywebapp.com in a web browser, it authenticates with myauthapi.com/oauth/token to get a token. At present it does this by sending the creds in the header Authorization: Basic
The token that is returned is then saved.
The web application then tries to get the data from an endpoint on MyServiceApi using this token:
Authorization: Bearer
GET https://myserviceapi.com/objects
or POST myserviceapi.com/objects
or GET myserviceapi.com/objects/objectid
or DELETE myserviceapi.com/objects/objectid
MyServiceAPI verifies the token with MyAuthAPI, but that isn't public-facing, so there's no issue there.
The issue is that, as you can see from the attached screenshot of the Developer Tools console in Chrome, anyone using the web application can see the Authorization header containing the credentials, and could then use these credentials to programatically gain access to the auth API to generate a token which can then be used on the service API endpoints.
I want to restrict all access to the API servers to only come from specific applications, such as MyWebApp, on mywebapp.com.
First, I think this question could better be asked in https://softwareengineering.stackexchange.com/.
Second, where MyWebApp is deployed? How it is being used? If it works with https, then the body is encrypted, and when you send the clientId and clientSecret, you should send it in the body, so users will not be able to see them.
Client Credentials Grant should only be used by confidential Clients. Thats because you can't hide the client_secret on non confidential Clients. Your frontend seems to be a non confidential Client.
Normally you should use the Authorization Code Grant with PKCE. But you would need users to authenticate themselves for that.
Feels like you need an architecture design based on standard flows, since OAuth should work like this:
Web app signs user in via an Authorization Server, using Authorization Code Flow (PKCE)
Web app gets tokens from the Authorization Server
Web app calls API with an access token
API validates token using data from the Authorization Server
API then trusts claims in the access token and uses them for authorization
See my Initial HTTP Messages blog post for an example of how this looks.

Reading authorization response for HTTP AD login

I am trying to implement Active Directory login for my webpage. The webpage is hosted on a Node.js server that can talk to a the AD server via LDAP (so it is not on the same physical machine right now).
To trigger the login request, I send a 401 and WWW-Authorize: Neogiate response to a GET request triggered when the page is loaded. This causes Chrome to open a Username/Password dialogue. However when I enter some info and click Submit, I do not see any of the username/password data. Instead I see this authorization: 'Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGNFAAAADw==' which when decoded is this NTLMSSP cE
I am not sure what to do with this token or how to proceed.
You are running into this error because the server is directing you for implementation and Protected GSSAPI Negotiation Mechanism. This is a Microsoft invention for negotiating a type of authentication to use for Web SSO (single-sign-on):
either NTLM
or Kerberos
You need to store this token into the localStorage or cookies.
For example when you get the token from the server you then can save this on localStorage like this:
localStorage.setItem('token', token);
Then when you call the API you then have to send this token to the server with the request.

Adal library with reverse proxy (asp webservice)

I am working on an app for some company, but I have some problems with the security measures in combination with the Azure ADAL library.
For security reasons they setup a ADFS authentication server with the guys of microsoft. So that my webservice can only be accessed by a token given by the authentication server.
I use the adal library to get this authentication token and inside the network I have no problems with accessing the webservice.
For outside the network, I need to go through the proxy, this using a reverse proxy. For authentication on the reverse proxy you also need to authenticate to the ADFS authentication server.
Here is an image to explain it a little bit better :)
For the inside phone
Send authentication request to the adfs authentication server.
Get back a authorization token.
Send a request for data to the webservice with the authentication token
For the outside phone
Send authentication request to the internal adfs authentication server. This needs to pass through the reverse proxy.
The reverse proxy sees that you are not authenticated and will first authenticate with the external adfs authentication server, before he will let you pass through.
This authentication will add a cookie inside the httpclient so that it knows the request is already authenticated.
Now it will request the authentication token, and because it has the cookie inside the request, it will not need to authentication anymore.
It will return the token to the phone.
I am now trying to request some data from the webservice, with the token in the request. But inside the Azure ADAL library I cannot get access to the cookie to add this to the request to pass me through the Reverse Proxy. So the reverse proxy will block me an instead of a data response I will get the login page from the reverse proxy back as an html string.
So the problem that I am trying to address is that I cannot get access to the cookie inside the Azure ADAL library, or is there any other fix I didn't seeing.

Using OAuth instead of Basic authentication?

We have a web service, which currently uses Basic Auth over https to authenticate user requests. We also have a website which uses the service, and a native Windows client, which also uses the web service. I've read about OAuth, and it seems like it's always used for giving or getting access to external resources, i.e. delegation, but I'm trying to understand if it's a replacement for Basic Auth.
I'm not quite sure how all the parts fit together. Do you use Basic over https to the website to retrieve a secret and then have the javascript which is making requests to the REST services authenticate to the web service using OAuth instead of Basic?
It seems that at some point the user needs to enter their username and password into a form. I'm not sure what typically happens next. Is this even a use case for OAuth?
If you have local database accounts for the users (Resource owners) then you can replace the basic authentication with the one of OAuth flow named "Resource Owner Password Credentials" flow.
It is very simple flow where you issue HTTP post to an end point specified in your HTTP server usually named /token The content-type for this HTTP Post action is x-www-form-urlencoded, so the post body will contain something like this grant_type=password&username=Taiseer&password=SuperPass
One the request is sent to the /token end point the server will validate the user credentials against your database store, and if all is valid it should generate a token (signed string) which contains all the claims for this resource owner (user). Then your client application should present this token in the Authorization header with each call to any protected end point using bearer scheme.
This token expires after certain period and you can configure this from the AuthZ server. You can read my detailed blog post Token Based Authentication to get more details.

Resources