Authenticate server to server communication - java

I am new in authentication/authorization. I need to expose some authenticated apis to be consumed by third parties (server to server). I read how I can do this and figured out that a good option is to use oauth2.
I want to implement this using java with spring boot. My first problem is how to generate client id and client secret. Can you help me with some advice/materials to implement this?
Thanks

For generating the Client-Id and Secret, this guide might be useful.
In all cryptographic affairs, try to find solid / well tested libraries, as mentioned in the article.

Client id and client secret is just a simple login / password pair. Usual constraint apply, just ensure that your secret is not too simple.
As there is only two party implied, the oauth flow is very simple (client credentials).
One server (the client) will consume resources on the other one (the resource server #EnableWebSecurity, #EnableResourceServer) using an access token acquired against the authorizations server beforehand. The resource server may also act as the authorization server (#EnableAuthorizationServer). The client is annotated using #EnableOAuth2Client.
If communication is bidirectionnal, both "server" must be resource server and client (and so have its own client id / secret pair), the authorization server may be independent or hosted by one or both server.

Related

Spring Boot SSL Client-Server Communication

I am rather new to Spring Boot and SSL. I have developed a SSL rest web server with server keystore, private key, server CA and that correctly handles mutual X.509 certificate authentication. I have tested, that works HTTPS requests with Postman and also Python Client and everything working correctly, both the server and client are successfully exchanging and validating each others certificates.
But my scenario is little bit different,
I have created and connected one Postgresql database to my spring boot application and I have created entities of tables with specific ID numbers and also REST endpoints which you can create, get entity etc.
So my scenario is following;
Python Client comes with specific ID number and makes a request
to one REST Endpoint which is available for everybody (permitted by server).
Spring Boot Server checks that ID number in database and creates a Client Certificate to the Python Client (which I am stucked right now.) and sends this certificate to Client.
After Sending the Client Certificate, Client can use it and communicate Server with Certificate
So question is following;
Is that possible to create a client certificate in runtime in java? If yes, how I can create it and send back to client?
Thank you for your time and response.
I have found the solution. If somebody needs similar solution, you can the following steps;
Create public endpoint in spring boot which you can take the given id number
Compare with your database and if it id number existed call an .sh file (use process)
In this .sh file, use openssl commands to generate a key, remove the passphrase from the key (if you used it), create a client certificate request and finally sign the certificate.
Finally send this signed certificate and private key back to client.
After all, your client can use your signed certificate with private key and use your secured endpoints.

Jetty client / server mutual authentication

I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)

X.509 certificates for authentication without using client SSL

I'm trying to improve some code that enables logging in to our application using digital certificates, probably certificates stored on PKCS11 tokens.
It's a Java client server application, with the server on JBoss [Wildfly], and a rich Java thick client. We also have a GWT/Javascript based web client, but this doesn't yet support certificate auth.
The current implementation uses 2-way SSL authentication if certificate authentication is configured, i.e. the server will require a client certificate when the connection is opened. This causes some problems, and in trying to find ways to address them I've been searching madly to see if there is a standard, 'Right Way To Do PKI Auth To A JBoss Application'.
However just about everything I have found on the subject seems also to revolve around using two-way SSL, which kind of implies that is the Right Way to Do It.
It seems undesirable to me, in that the network transport is quite a low-level concern, heavily separated from the application logic and stuff like authentication and user management.
In order to prove the client is a valid user of the system (as opposed to merely someone with credentials endorsed by a CA in the server trust store), the server application logic has to rummage around looking to find the certificate that was used on the incoming connection in order to scrape the Common Name off it. I've discovered that javax.servlet.request.X509Certificate is a standard-ish parameter one can query on the servlet, so it ought at least to be possible.
The other architectural problem this causes is that our app requires reauthentication for the lifetime of certain sensitive operations. If one is using the SSL connection to prove the user has the private key, then logically that would require opening a whole separate connection.
Logically, authenticating with a certificate would seem to require
The server generating a nonce
The client encrypting the nonce using the client's private key
The client sending that encrypted value to the server with the accompanying public certificate [or certificate chain].
Now, that is exactly what happens during an SSL handshake, but obviously a whole load of other baggage comes with it that is irrelevant to the application-level concern of authenticating the user.
I thought about implementing the steps directly myself, but this would seem to violate the first rule of crypto (Don't implement your own crypto).
If the server generates random nonces then that introduces a level of chattiness and statefulness to the process, which is doable but a pain when you are striving for a stateless and clusterable server.
Time-based One-Time Password implementations circumvent this, and seem to be a standardized mechanism for 2-factor authentication that is getting support from Google+ and the like.
However I can't find anything in the way of out-of-the-box libraries that will let me build an implementation using certificates directly from an imposed PKI.

How to secure communication in client-server app?

I've got backend running on the tomcat server and client running in the browser. Application is built on Spring 3 MVC + Spring security framework. How to secure the communication ? Is there other option than just to set the server to be accessed only via HTTPS ? I've got no experience with this so it might be a stupid question, but will this affect my application and do I have to set something up in my app, when the server shall communicate with client via GET/POST request via https ?
It depends somewhat what you mean by "secure." If you want privacy, you must use TLS (SSL) as a transport.
If you're only concerned with authentication, then you have another option: Digest Authentication.
Digest Authentication allows the client (browser, usually) and the server to exchange authentication credentials in a secure manner without securing the entire communication. If you use Digest Authentication, then third parties can still:
See what data the client and server exchange
Insert themselves between the client and server and alter the exchange
What third parties cannot do is spoof the authentication or steal username/passwords in transit.
If that's not secure enough, you need TLS. You do not necessarily have to purchase a certificate. You can use OpenSSL to generate your own. This certificate will not automatically be trusted by browsers, however, so you can't really use it for public sites.
You will need to consult your server documentation for how to set up HTTPS or Digest Authentication, depending on which fits your needs.
Your application should not be affected by switching from HTTP to HTTPS, Tomcat handles this or maybe an Apache in front. It's important to understand, that HTTPS is a server-thing, not an application topic, because the client makes a connection to the server (Tomcat), not to your application. Check out the Tomcat documentation, it's pretty clear about how things work.
And, like the others said: From what you've said it's best to use HTTPS (TLS/SSL). Certificates are a bit frightning at the beginning, but it's worth to invest the time.
HTTPS is the (S)ecure form of HTTP, since you have an HTTP client server application I would certainly used HTTPS. All you need is to create an SSL certicate for your website and restrict access to your website to HTTPS only, then you are 99.99% secure.
Your certicate can be either commercial from Versign or equivalent or some open source engine.
for the clients nothing needs to be done to support HTTPS

SSL and authenticating users

I have a REST API which clients connect over SSL (self signed cert 2048bit)
I was thinking of implementing the following security
The client requests a RSA public key from the server
Encrypts the username / password
Adds these to the header of EVERY REST call allowing the server to be stateless
The application involves users adding credit cards (the numbers themselves are encrypted) and purchasing products so security is critical
We also have very limited time from a iphone client point of view so I was hoping if the above would be suitable?
Usually, when it comes to security, one doesn't want to reinvent the wheel. It's way better to use state-of-the-art technologies, so you'll benefits from others' (likely more skilled than you) work.
If you have a RESTful API on SSL, I don't think you have written your own custom TCP protocol. Likely you'll use HTTP, so since it's on SSL, you are on HTTPS.
When using HTTPS, your browser makes sure that the request is signed and encrypted so that only the other end (the service) can authenticate the client and decrypt the message. So there is no need to encrypt data and using custom headers. A simple cookie-based session is enough so you don't send users' passwords in every request.

Categories

Resources