Ajax authentication without letting browser pop up login dialog - ajax

I am desiging a RESTful Web Service (JBoss + RESTeasy). The UI programmer is writing an Ajax web app that will use it. The web app will be one HTML page with everything done in JavaScript. For security, all traffic goes through SSL.
Currently I'm using Basic authentication. The UI programmer can show a dialog to get a username and password and put "Authorization: Basic xxxxx" in the header. Unfortunately if the password is wrong, the ugly browser login dialog box comes up. Also there is no way for the user to log off. This is unacceptable.
There appears to be no way to intercept a 401 response to an XMLHttpRequest in any of the browsers we will use.
Form-based authentication won't work for us. We need an automatic logoff after some period of inactivity (the equivalent of a session timeout). We can't have the server suddenly return a login page when the client expects a JSON object.
JBoss offers four authentication strategies: BASIC, FORM, CLIENT-CERT and DIGEST. I think DIGEST has the same problem as BASIC. None of the four is what we want.
This web application will be the only client (for now) so there is no requirement to use BASIC. Is there any other authentication strategy I can install? For instance is there an implementation of WSSE UsernameToken I can use? (As described in Chapter 8 of the O'Reilly RESTful Web Services book.) The server would send "WSSE" instead of "Basic" in the WWW-Authenticate header and presumably the browser would ignore it and pass it right through.
I want to configure security where it belongs -- in the JBoss configuration files, not in my RESTful Web Service -- so I'm looking for an implementation I can just plug into JBoss.

The browser won't present the password dialog if it doesn't recognize the authentication scheme in the WWW-Authenticate header. Your best bet may be to continue using basic auth on the server while setting the header manually to something like "Basic/MyApp" for 401 responses.

Related

Can't understand how to work with OpenID protocol using openidConnectClient-1.0 feature and Angular application which using REST API endpoints

So, I have a WAS Liberty server which configured to work with OpenID provider. Then I have an Angular application which heavily using REST Api endpoint.
When I first open an application or open it after token has been expired everything is ok, WAS redirects me to OpenID provider and then regular flow defined by OpenID and backed by openidConnectClient-1.0 implementation.
But how do I suppose to care about following use case: token has been expired while the application were open, and user issues GET or POST request without reloading the application? Right now WAS perform redirect too, so I can't actually distinguish between regular response and redirect (both return status 200).
The only solution which I think about is to say to Websphere not to perform redirect for some endpoints but to return 401/403 errors. So I'll be able to monitor response codes in my client side and perform accordingly. Is it possible to achieve? Perhaps there's another solution which I didn't know about?
Update: After I've written this I thought about using Authentication Filters, i.e. define something like:
<authFilter id="testFilter">
<webApp id="simple" matchType="contains" name="simple"/>
<requestUrl id="excludeUrl1" matchType="notContain" urlPattern="/basic"/>
<requestUrl id="excludeUrl1" matchType="notContain" urlPattern="/api"/>
</authFilter>
But I immediately see two drawbacks on this approach:
Maintain app's logic in two different places, server.xml and app itself. It'll make maintenance of the application very cumbersome.
Due to nature of Authentication Filters it will fallback to another registry to perform login. It potentially can be a security flaw.
Update 2: Solution from above doesn't work. When server returns 401 Error together with www-authenticate header, browser shows popup of basic authentication, see proposed solution below.
To resolve this issue I've used Angular's Interceptors, where I check if there're following headers within the response: no-cache, no-store, must-revalidate, private, max-age=0. If they persist within the response I know that session expired and perform reloading of my application.
While reloading, liberty itself redirect it to SSO provider. Another solution is to extract redirect URL from response and redirect to it manually.

WCF over HTTPS Basic Authentication with LDAP

I'm currently working on building a WCF web Service, I was asked to use Basic Authentication over HTTPS and also to validate whether the user is present in an LDAP group for Authorization.
I searched in Internet and it is said that Active Directory Authentication is not available in IIS and we should use our own Custom Basic Authentication Module or UserNamePasswordValidator.
Link I used for coding Custom Authentication Module
I have hosted the WCF in local IIS with SSL and now it is running under https.
The question is, If I implement this one, I need to add the Authorization header manually it seems. Is there any other way I can get the User Name or Password entered in the Basic Authentication dialog which is showed when we open the service in a browser ?.
OR
could you please provide an advice on what are the things I need to do to implement the above said Security ?
I'm helpless and requesting your help on this !!!!. Thanks in Advance.
Background:
I also tried UserNamePasswordValidator, but it was doing at the Application level, I was able to view the wsdl file (Meta data of the web service without even providing credentials) so I did went with the Custom Basic Authentication Module.
With Custom Basic Authentication Module , it is asking for credentials before the svc is opened in browser. So I think this would best suite. Please provide your valuable suggestions.
Basic authentication works by the web server returning a 401.0 status code AND a WWW-Authenticate response header with the value 'Basic real="xxx"' where the realm is simply information shown to the user so that they understand what is asking for the authentication. When the browser receives this type of response, it displays a dialogue box to the user asking for a username/password. The browser then re-submits the originally requested URL, but also includes an 'Authorization' header whose value is a base64 encoded string which includes the username and password.
A custom authentication module for IIS basically has to handle this interaction. For each request that comes in, it needs to see if there is an 'Authorization' header, and if so, it extracts the username/password, authenticates them in whatever fashion it likes, and if successful sets up the Context.User. If there is no 'Authorization' header, or the username/password are not valid, then the module must set the response code to 401.0, and ensure that there is a WWW-Authenticate header (as described above).
In order to use the module, all other authentication modules in IIS must be disabled (although there seem to be some circumstances in which the anonymous authentication module should be enabled). Due to caching in IIS, don't be surprised if not all requests are passed to your authentication module.

Spring security, AJAX and SiteMinder

I am implementing Spring Security login and I am trying to understand something, here is the scenario I want to implement:
For initial login show login page and let user in.
If after some inactivity session expired and user makes some action show him popup window to authenticate (js-based popup in browser). Continue with the action like there was no login form.
Implementing form is easy, but how do I make the popup work - let's say I make the request to some protected URL after session expired, how do I make sure it's not forwarded to login page, but to my login handler that shows popup window?
Another issue - I need to integrate with SiteMinder, so I would need to read the Login/Password combination and after it's read, forward to SiteMinder for authentication, after that's done I want to return without forwarding.
Answer to SiteMinder issue:
Siteminder is generally installed on a Webserver behind your servlet container.
Also, Siteminder manages the authentication and an application does not have access to a user password at all.
To integrate with Siteminder use this filter:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e6295.
Answer to the login with the popup issue: since you need to integrate with Siteminder, I would not recommend to implement the login via the popup.
The sample given on the above springsource website is quite primitive and can break in several use cases. Using the SM_USER header alone has several caveats, see my answer here: How to validate SM_USER header in Spring Security preauthentication for siteminder
CA SSO aka SiteMinder, as well as other traditional html-form-request-response SSO systems, have a hard time dealing with Single Page Applications and protecting the web services that you invoke via AJAX, without breaking the flow of your application.

Securing REST calls made by JavaScript from an unsecured page

We have a web-based application in which we are not requiring end users to login. The application uses Ajax to make calls to REST services hosted on the same server. Besides this application, we want to make sure that if any other applications / agents call the REST service they get denied.
What is the simplest way to secure a REST API like this? My guess is that we would include some sort of security token and make the call through HTTPS. However I'm not clear how the Ajax application would create/obtain/encrypt the token and generally what the lifecycle looks like.
I would rather do this outside of Spring Security or OAuth if possible. I have also read that sending username and password over SSL is enough for authentication. In this case, the app would have a "username" and password and it would send it with every request to the REST service. But how would it keep that information secret if the client is just HTML and javascript in the browser?
Thanks.
In general this is impossible. Someone could just do view source on your javascript, read the token, then do whatever they want.
https is not necessary here. For the token, probably the easiest is to set a cookie when they download the javascript from the server, then that cookie will also be transmitted with any AJAX requests.
This is not really secure - anyone can just see what the cookie is and use it, but it's the best you can do.

storing login state without a session (GWT)?

I just thought about writing a GWT app that just works as a client for a RESTful web service. The web service requires HTTP basic authentication for each call.
Since the client is not 'connected' with the server over a session, I have to remember the authentication credentials on the client side. I could do this within the GWT application, but with this, the client has to log in after every reload, which is not very beautiful. I also don't think it's a good idea to write this information to cookies, since everyone could read them.
So, who knows what I am looking for? :-)
Browsers save the username/password information for a given server/port/domain. So if the client has to login once (at least via the browser standard BASIC http dialog) it's preserved over the reloads.
I don't know if you can do that. Maybe forcing the user to navigate to a page inside the domain (or realm) and then using GWT...

Resources