Rewriting inbound Java server authorization headers prior to authentication - java

We have a REST API delivered via Apache Tomcat that a Flash web application is intended to communicate with.
Authentication is performed with Basic auth over SSL (although the password inside the basic auth is SHA-2'ed). The issue is that using basic authentication for the Flash client is causing the standard browser log-in box to appear because of "WWW-Authentication: Basic" in the header. Flash is unable to bypass this by manually setting the Authorization header prior to the request.
Other clients need to be able to authenticate via the existing mechanisms, so rewriting the authentication logic would not be ideal.
I have the idea that the authorization headers sent to and received from flash client could be dynamically rewritten to use another name for Basic auth which would cause the browser not to understand the auth mechanism and not present the dialog box. Authentication headers to and from Tomcat could be rewritten from "WWW-Authenticate: Basic" to "WWW-Authenticate: PretendBasic" but ideally the built in container security could still handle the basic auth after the rewrite.
I wrote a filter to rewrite inbound headers as "WWW-Authenticate: PretendBasic" as "WWW-Authenticate: Basic" hoping the next filter chain would be auth and the request would be handled as normal. Unfortunately the Servlet specification states that a filter cannot be inserted prior to authentication. I think the only possibility of this working is to create a stackable JAAS authentication module that would first perform a header rewrite on requests if coming from the Flash client, and then pass authentication through to the existing container managed security systems.
Since I'm unfamiliar with JAAS, I'm hoping the community could shed some light on how to accomplish this, and whether it is a good idea in the first place.

If your flash application always works with server protected with basic, it can ask for the credentials prior to generating the first request to the web services. So the first request will already include the authentication header and you won't receive 401 in response.

I would have thought that enabling authentication via WWW-Authenticate, as an imitation of HTTP Basic, would do the trick.
Where you currently have HTTP Basic authentication working, just add another authenticator which does HTTP Basic but against the WWW-Authenticate header instead of the Authorization header.
You can then include the header in Flash and ignore HTTP Basic in that client.
I've done similar, using 3 different authentication schemes, on Jetty. I'm not sure what the Tomcat way would be.

Related

How to make sure user is being authenticated from my app with POST request?

I am writing an android app that connects to my server with a POST request. So far, I am using SHA-256 to hash and salt epoch time and use that as a third parameter alongside the username and password to make sure that the authentication is done from the app. However, an attacker could decompile the apk and figure out the salt that I am adding to epoch time, allowing them to make a POST request from wherever.
I am wondering if there is a way to make sure the POST request is being made from my app. Note that I cannot change the authentication method of the server from POST.
Thanks in advance.
HTTP Client authentication is an open process to allow vendors to implement different authentication schemes.
Apart from SSL (when run under HTTP protocol) having is own authentication mechanism (for servers and/or clients) the authentication task on HTTP protocol is managed by the WWW-Authenticate header in the HTTP header protocol. That field reflects if the server demands some kind of authentication and how the peer is going to be authenticated.
This allows peer protocol authentication (not only for the client, but also the server can be authenticated) but it makes HTTP method agnostic, as the authentication procedure is orthogonal to the method used to request information. You can use authentication with any (or all) the http methods (GET, POST, CONNECT, HEAD, PUT, DELETE, etc)
You need to read the RFC's docs: 7230, 7231, 7232, 7233, 7234 and 7235.
The more interesting to you is 7234 (it describes protocol authentication), and the documentation of the web server you are requesting to, and how the service has been configured, to get an idea of the authentication methods it supports or the credentials you must provide to authenticate the client.
Normally, the process is as follows:
the client makes a unauthenticated request of info for the target url.
The server denies the request, signalling authentication must be used, and proposes an authentication method and challenge.
The client redoes the request, but providing the requested credentials from the server.
The server accepts the request or denies it again.
To note is that, depending on the authentication method to use (e.g. BASIC is a simple username/password scheme, while DIGEST forces the user to produce a digest, based on used credentials and some server provided info) you can need more than one roundtrip to the server (the server can force you, while not common, to use two of these in chain to grant you access to the resources)
In the case of Java, probably a good source of documentation is the Apache HttpClient class, and it has some tutorials from Apache that show you how to make authenticated requests. A good reference is this.

Secure the communication between website and our RESTful web service

we will have a website created by an outsourcing company, that website will send some information in JSON payload to our RESTful web service. The user will do login and authentication on that website, so we don't want to know the username and password of the user. And what we need is make sure the JSON where sent from is that trusted website then we will send back another JSON payload with including some info from us.
I am pretty new in the security area so I have googled a bit to find out we can use certification to encrytion/decrytion the message. But what will be the solution if we can identify the hack request in the first place and rejecting that request.
As of your description, there are coming two things in my mind immediately:
Use an SSL certificate. That already ensures that your
site is being transferred encrypted over the internet.
Use a token system. Tokens are widely used in payment solutions for example - as credit card data should never touch your own server. All tokens contain some secret information that are used to prove identity.
Use HTTP request headers eg. Basic Auth
For sure, you should have a SSL certificate. This adds already a lot of security to your site.
But what will be the solution if we can identify the hack request in the first place and rejecting that request.
Well, you have answered it yourself. If you can detect it, reject it.
A simple way to protect your restful service is something like basic auth. The application making the rest call would provide a request header like
Authorization: Basic ZWx1c3VhcmlvOnlsYWNsYXZlde
This would not be a user-based solution, but a webapp to webapp solution. All other requests would be unauthorized.
https://en.wikipedia.org/wiki/Basic_access_authentication

Restricted HTTP requests to web server from Android

In the application I am currently working on, I need to implement a way to restrict an HTTP POST request to upload media to the server.
I already have registration implemented so is the best way to do this to send a Basic authentication header with every request?
I have no interest in implementing any kind of DRM in my app, so it doesn't matter if the request came from my app or not.
I suggest you to use HTTP BASIC authentication along with HTTPS in every request. Every kind of data is entirely encrypted and web services are secured with authentication.

How to send AuthnRequest without user-agent interaction using HTTP POST?

My question is similiar to How should I be implementing the HTTP POST Protocol Binding for SAML WebSSO Profile?, but I don't see exact answer that I needed. This is my case. I already implemented Service Provider for WEB SSO SP-initiated POST redirecting and my IDP is active directory and STS is ADFS2.0. After user log on, I need to send another AuthnRequest to ADFS2.0 without user agent interaction. Is it possible with HTTP POST? Or to send over HTTP POST, user agent interaction must needed. I set isPassive=true. I try to implement using Java.
Ok you could build an authentication request and send it to ADFS2 using any HTTP client (i.e. http://www.innovation.ch/java/HTTPClient/ works for me). But ADFS2 will always reponse you with the Login Form. The problem is that in the request you were missing the cookies that ADFS2 is using for tracking your session (SamlSession cookie).
Hope it helps,
Luis
ps: why do you need to send another authn request?

Supplying credentials safely to a RESTFUL API

I've created a RESTful server app that sits and services requests at useful URLs such as www.site.com/get/someinfo. It's built in Spring.
However, these accesses are password protected. I'm now building a client app that will connect to this RESTful app and request data via a URL. How can I pass the credentials across? Currently, it just pops up the user/password box to the user, but I want the user to be able to type the username and password into a box on the client app, and have the client app give the credentials to the RESTful app when it requests data. The client is built using Struts.
Cheers
EDIT - I don't think I made the question clear enough. I'm already forcing HTTPS, my question is more, in-code, when I'm requesting data from www.site.com/get/someinfo, how do I pass my credentials alongside making the request?
You more or less have 3 choices:
HTTP Auth
Roll your own protocol, ideally HMAC challenge/response based
OAuth
OAuth is currently susceptible to a variation of a phishing attack, one that is largely undetectable to the target. As such I wouldn't recommend it until the protocol is modified.
OAuth should also be a lesson about how difficult it is to design secure protocols, and so I'm hesitant to reccomend the roll your own route.
That leaves HTTP auth, which is likely best if you can use it.
All that said, almost everything on the internet uses form based authentication, and many don't even bother with https for transport level security, so perhaps simply sending the password text in the clear is "good enough" for your purposes. Even still I'd encourage using https, as that at least reduces the dangers to a man in the middle attack.
If you can add HTTP headers to your requests you can just add the Authorization header:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where you're using basic authentication and the QWxhZGRpbjpvcGVuIHNlc2FtZQ== bit is "username:password" base64 encoded (without the quotes). RFC 2617
Well, https has nothing to do with authentication, it's just transport-level encryption.
if you interact with an HTTP api, be it that it's https or not, and the dialog box pops up, it means its using HTTP authentication, either basic or digest. If your client instantiates an http client to read data from those "services", then you can pass those credentials when you instantiate the object.
If you use client-side script, XmlHttpRequest supports http authentication as well.
So in terms of code, how you pass the credentials to the RESTful services is dependent on the http client you're using (the object you instantiate to retrieve the data). You can simply collect such a username / password yourself from the client, and use it to call the other service.
look at existing solutions. In this case, oauth

Categories