http authentication dialog not popping up - spring

I'm trying to call(spring ) rest API which is protected using digest authentication using spring security and trying to access it from the redux front end. I'm getting a 401 response back to the front end, which has the response header WWW-Authenticate: also .. but unfortunately I am not getting the http basic authentication pop in my front end to enter the username and password.
Can someone help me in identifying the possible reasons for this? I'm able to get the http authentication pop up when I hit my rest API directly through the chrome.

Unfortunately, XHR requests do not trigger the auth pop-up. This will only happen if the main request (the html page you are loading or a redirect you make from that page) throws a 401.
The auth screen is also triggered if you load the request in an iframe. However, the credentials provided using the basic auth screen will not be passed on to other XHR requests. If you do use an iframe, you should respond with some sort of cookie and the subsequent XHR request should not need the basic auth screen again
Your options are:
Catch this error in your javascript and ask for the password using some interface you create yourself.
Make the same request in an iframe (or another request that will trigger the same security restriction) and respond with a session cookie upon success, then trigger the XHR.
Make an Login UI and ask for the credentials upfront, as you will need them for the XHR request.

Related

Browser sending old "Authorization" header for subsequent requests

We are experiencing an issue with Browser sending Authorization header of initial request for subsequent requests to the same requestURI.
Problem:
We have a webproject which has user specific business logic so we have this login logic where for the initial request, if we don't have a existing session we send a 401 response along with WWW-Authenticate: Basic realm="production site" header to get credentials via the client and the browser issues a rerequest with the Authorization header and we use it to create a sesssion and initiate the login process.
But however, once the browser cache & cookies are cleared the session gets destroyed but we are still getting the old(Got from the initial request) Authorization header sent to that URI.
We susupect it was cache issue but not sure.
Can someone please help us to understand whats happening here and why we are getting the same Authorization header everytime. Thanks in advance.
Basic/Digest authentication usually gets stored separate from the cache and is unrelated to cookies.
The server doesn't have a ton of control over this, but one way to force the browser to clear credentials is to just send a 401 with a new WWW-Authenticate header (even if the credentials you got are correct, you basically need some way to track that the intent was to log out), but this will create a new login dialog that the user will need to dismiss.
I'd recommend not mixing cookies and HTTP Authorization. You don't need sessions because you already know who's making the request.
Generally HTTP Auth in browsers kinda sucks and browser developers have not done a good job creating a good UX for this, which is why almost everyone just renders HTML login forms instead.

How to secure web api with Identity Server 3

I'm building an MVC web app that uses the openID Connect hybrid flow to authenticate with Identity Server 3. The MVC web app contains jQuery scripts to get async JSON data from een ApiController. That ApiController is part of the same MVC web app.
I don't want that everyone is able to access the data from the API, so I want to secure the API as well. I added an [authorize] attribute to the ApiController. When requesting the API with a JQuery ajax request I get the following error message:
XMLHttpRequest cannot load
https://localhost:44371/identity/connect/authorize?....etc.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:13079' is therefore not allowed
access. The response had HTTP status code 405.
But, when I do a request to the API method directly in browser, I will be correct redirected to the Login page of Identity Server..
So, what's exactly the problem here? I read something about that requesting the /authorize endpoint is not allowed via 'back-channel', but I don't understand what's the difference between 'front-channel' and 'back-channel'. Is it possible that I mixed up the wrong OAuth flows? Is the Hybrid flow not the correct one maybe?
I also find out that the API is often a seperate app, but is it always neccessary / best-practice to build a seperate API app that for example requires a bearer token?
Please point me in the right direction about this.
The authorize method on your identity server does not allow ajax calls. Even specifying CORS headers is not going to help you in this particular case. Perhaps you could return a forbidden response instead of a redirect and manually redirect the client to the desired location via window.location
You need to allow your IdentityServer to be accessed from other domains, this is done by allowing "Cross Origin Resource Sharing" or CORS for short. In IdentityServer the simplest way to allow this is in your Client configuration for your Javascript Client, see this from the IdentityServer docs on CORS:
One approach to configuing CORS is to use the AllowedCorsOrigins collection on the client configuration. Simply add the origin of the client to the collection and the default configuration in IdentityServer will consult these values to allow cross-origin calls from the origins.
The error you're seeing is the browser telling you that when it asked IdentityServer if it allows requests from your Javscript client, it returned a response basically saying no, because the origin (http://localhost:13079) was not specified in the "Access-Control-Allow-Origin" response header. In fact that header wasn't in the response at all meaning CORS is not enabled.
If you follow the quickstart for adding a JavaScript client from the docs here all the necessary code is detailed there that you need for the Client config and to setup IdentityServer to allow CORS.

WAAD doesn't refresh access token from javascript

For applications that authenticate users with Windows Azure Active Directory(WAAD), unable to refresh token from javascript.
All the resources are protected by Authorize attribute makes calls to login.windows.net/{0} if token is expired. If the request is from page load it works as expected but if the request is from javascript ajax call it is unable make call to login.windows.net/{0}. It returns with status 302 and message
XMLHttpRequest cannot load https://login.windows.net/xxx.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'xxx' is therefore not allowed access.
How to refresh the token from javascript calls?
It looks like you secured your web API with a method more suited for web UX.
Take a look at ADAL JS for a more reliable way of dealing with javascript driven apps: http://www.cloudidentity.com/blog/2014/10/28/adal-javascript-and-angularjs-deep-dive/
For an explanation of how token renewal works, see the video linked in that post
HTH
V.

AJAX calls to web service with HTTPS protocol

I plan to use https to build a website. After the user logs in, s/he is directed to a dashboard. The dashboard will be developed using javascript and html5. What are the thing I need to keep in mind when I make ajax calls using SOAP to a web service while using https?
The most important things:
always use the same domain name, otherwise browser will throw cross domain errors,
always use https protocol for every ajax request, so browser won't get same origin errors.
On the server side check for X-Requested-With: XMLHttpRequest HTTP header, to be sure that the request came as AJAX, not standalone GET/POST request. This is only difference.
With AJAX request browser will send the same cookies value as in the any other request, so you can surely check user session with it.

Cookie set by asynchronous HTTPS request not showing up

I have a website that uses asynchronous http requests (ajax, to use the common misnomer) for performing login and registration. The authentication cookie is set by the asynchronous request and it all works great.
I recently locked down the registration and login actions to require https. Everything appears to work, except that the authentication cookie returned isn't functioning properly and the user doesn't actually get logged in.
In Chrome, in the development tools, under resources, it doesn't show any cookies having been created. If I go to the Chrome settings and view all the cookies, I can see that a cookie has been created. Perhaps it's encrypted and not readable?
So, to summarize:
The initial page is loaded using normal HTTP
The Login action is an asynchronous HTTPS request
The authentication cookie returned by the HTTPS request doesn't seem to be working
How do I get this to work?
A couple things I should note:
This is not a CORS issue.
I am aware of the potential man-in-the-middle attack. This website does not house sensitive data. I'm attempting to do something very similar (if not exactly the same) to what reddit is doing.
I managed to figure this out. Turns out that in the Http response, you need to set the Access-Control-Allow-Credentials header to true. Also, you must set the withCredentials to true on the client-side http request.

Resources