Alternatives to Basic Authentication when logout is required? - java

If BASIC authentication was not build to handle logging out, what alternate authentication methods exist for authenticating backend services that need to be able to log out?
I found these references stating that BASIC auth is not able to do log
out without some hackiness:
How to log out user from web site using BASIC authentication?
How do I log out?
We are using BASIC authentication to log into backend applications, and FORM authentication for frontend applications. After our team tested the stack on FireFox/IE, it was found that a user would not be able to log out if they logged into the backend services via BASIC authentication on those browsers. The hacks and workarounds are unacceptable to my team (asking user to enter incorrect credentials, making user close browser, use javascript to send incorrect credentials, ask user to clear browser cache, etc), so we are seeking advice on alternative authentication methods that DO allow logging out
EDIT- My temporary workaround for logout:
I am currently getting around this problem by using FORM authentication. One problem is that my backend services rely on the shared frontend login.html form, and another problem is that Postman does not support logging in via a redirected FORM input, and our client Arquillian calls blow up from the login form.
FORM authentication gets rid of the "I can't log out with BASIC" problem, but now I can't authenticate as straightforwardly.

Form based-authentication
If it's okay to keep the session state on the server, you can go for form-based authentication.
Send the credentials in the form, if the credentials are valid, the server will issue a cookie that will be sent back and forth to identify the session on the server. To logout, the session can be invalidated:
session.invalidate();
You also can configure your application to expire the sessions due to timeout:
<session-config>
<session-timeout>60</session-timeout> <!-- minutes -->
</session-config>
Token-based authentication
If you want a stateless mechanism, go for token-based authentication.
The client exchanges hard credentials (such as username and password) for a piece of data called token. For each request, instead of sending the hard credentials, the client will send the token to the server to perform authentication and then authorization.
For the token, you could use JSON Web Token (JWT). It's an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
JWT is a generic name for the following types of token:
JSON Web Signature (JWS): The payload is encoded and signed so the integrity of the claims can be verified.
JSON Web Encryption (JWE): They payload is encrypted so the claims are hidden from other parties.
The image was extracted from this page.
The token can define an expiration date in the exp claim. For logout, you can remove the token from the client.
You also could keep the track of the tokens in a whitelist on server-side and invalidate them as you need. There's no need to store the whole token on server side though: Store only a token identifier in the whitelist and use the jti claim to store the token identifier in the token.

I suggest you to have a look at Apache Shiro, especially the way session are managed (https://shiro.apache.org/session-management.html).
They have namely abstracted the concept of session so that it can work in various situations: in a webapp (in such case, it's simply a wrapper around the HTTP session), in a standalone app, etc...
In your particular case, the front-end could open and close (logout from) a Shiro session that is shared with the backend layer.
See the sentence:
Heterogeneous Client Access
(...)
For example, a (desktop) application could ‘see’ and ‘share’ the same physical session. We are unaware of any framework other than Shiro that can support this

Related

Spring Boot with common Authentication

I am trying to set up authentication server for spring boot application. I have multiple microservices application. Let say hospitals, patients, reports applications. I have each of microservices service application to be authenticated before allowing user to access the resources.
Can I know how can I have common authentication logic as a separate application. let say authentication application. I am planning to us (spring security with Auth 2.0 and JWT token).
For example:
When user tries access hospital dashboard page, we will check the user is authenticated
First we need to check whether user is authentication if not I need
to redirect to login service in authentication application.
Once user is logged in, then when he try to access dashboard we will
check the token is valid. If valid then allow user to access the
dashboard service.
Now user try to access patient details which is there in patient.war as a separate project, as the user already logged in we need to valid token, then we need to allow access to resources API what he is trying to access. If token is invalid then we need to redirect to login page.
Question:
I have gone through some example they have authentication server and resource server as separate application. i.e #EnableAuthenticationServer and #EnableResourceServer. But I have noted this got deprecated in latest spring boot version if I am right. Please correct me if I am wrong.
How can I have authentication functionality as common war file and let the other resource server access it before allowing the user to access the reset service API?
Which is the right way to build a microservice application?
I need some experts help to understand the best approach we need to implement authentication and authorization in latest spring boot version.
This is a relatively older question but I'll answer since it may help others.
For any microservices-based architecture, the api gateway is an important aspect and it should be there.
All your microservices will be hiding behind the gateway and any calls made to the downstream services (hospitals, patients etc) will go through the gateway.
This gives you multiple advantages.
You can add login (authentication) functionality in the gateway
You can put rate limiter to avoid DOS attacks
A single point of entry for the outside world so your clients don't neet to know the URL of each microservice
Now, the way it works is:
The client sends username/password or client_id/client_secret to the /login endpoint which is inside the gateway (for example GatewayController)
Gateway sends credentials to an "Auth-Service" which authenticates the user from a db or anywhere and creates a JWT (Oauth token)
Gateway returns the jwt back to the client
Client calls the, let's say, /patients endpoint through gateway with the jwt as header "Authorization" parameter
Gateway -> Auth-Service (To validate the token)
If invalid, 403 forbidden is sent. Otherwise, request is forwarded to the downstream service (in this case Patients-Service)
Patients-Service sends the jwt token to Auth-Service to get permissions from inside the token since we know that the token has already been validated.
Once the permissions list is received, the Patients-Service matches them with the permissions mentioned on each api (for example PatientsController)
If any permission matches, the response is served. If not, 403 forbidden is served.
To make it more clear, Auth-Service is called once when the call is for login(authentication). Auth-Service is called twice for all other api calls(validate + permissions).

Secure REST endpoints with service user or public user

I'm writing a mobile app that communicates to a remote Java service via REST. I have protected my (SpringBoot) web service with https protection (due to the nature of the data, it needs to be secure) but my question is about which user/password I use to secure the https calls.
Should the username and password I use in the https header be a service account that the client (mobile app) and Java service knows or should it be the public user's username and password? The easiest option is just to use a service account but this means the mobile app will have those details built into it and distributed publically (albeit in compiled form).
Going the other way and using the user's username and password means I'll have to have the logon REST endpoint open and unsecure (which is fine I guess), but it just makes it slightly more fiddly.
Good question, and I would reckon you to use token based authentication and authorization scheme. Firstly you should have a login page where client logs in by providing username and password which is authenticated by calling some remote login service which maintains it's own user store or may use an existing one in your organization if any. Upon a successful authentication, the auth service should provide the client with a valid token, which then be refreshed time to time. The mobile or web client should pass in the token to the downstream microservices when a request is sent and this token should be sent inside the Authorization HTTP header.
Exposing the username and password while passing it around the network normally not considered as a good solution and that's where token becomes handy too. Token is the normal procedure that people use to secure rest endpoints. Yous rest endpoint should intercept each and every request comes at it, passes the token to the auth provider and verifies that. If the token is valid it will allow the request otherwise it should deny it.
Security is a pretty much larger topic and you have X.509 certificates other than tokens to encrypt the data sent across the wire over https and so forth. I suggest you to take a look at the spring security documentation since that will be a good starting point. Spring Security gives lots of hooks for developers which can be used out of the box with some sensible defaults. You can use JWT style tokens, Oauth tokens and spring security supports all these different forms too.

Token based login and authentication in java

I want to know how the token based authentication is done in Java. I want that if I hit my application then the system should redirect it to the login page and once the user enters the credentials, the user shall be validated and authenticated. Once authenticated a token should be generated which shall be handled across client and server. My concern is if the token is generated, how it is being passed to the client and how the client sends it back to the server on every request processing. I know that it has to be set in header. But my question is how exactly. I know we have spring and all but I want to know how it is being done using jsp and servlets.
I went across few websites but unfortunately could not find the expected result. A small demonstration shall be very helpful. Thanks in advance.
There is no such authentication token. There is a session token defined in J2EE Web Application server standard (https://docs.oracle.com/cd/E19644-01/817-5451/dwsessn.html). Once the JSessionId is established between server and client it is used to manage the user.
For example if you build you own authentication system you can bind the jsessionid with user login attempts, and keep a list of jsessionids which has logged in successfully. This is basically what authentication frameworks do.
Also, you can check this Under what conditions is a JSESSIONID created? and this: Spring security FAQ

Sharing REST tokens between servers

I have a requirement for a REST API that has token-based authentication: we will have replicated application servers with a load balancer, since tokens are generated by one server when a user is authenticated, and different requests from the same client can be handled by different servers, is there a generic technique or technology to share those tokens between the different servers?
About technologies, we will be using the Java stack, more specifically Grails.
About the application servers, we might have more than one database. This comment is important because discussing with colleagues, someone suggested to manage the token sharing using the same database from all application servers. I'm looking for a solution that doesn't need a centralized database, that let us scale on the DB side.
When using token based authentication, there's a server that authenticates the user and issues a security token. Authenticating the user can be done in many ways (verifying username/password against a database, verifying a certificate on a smart card etc).
Once the token is issued and signed by the authentication server, no database communication is required to verify the token. Any service that accepts the token will just validate the digital signature of the token.
The client (caller of your service) is responsible to send the token along with the request. So no matter which server behind your load-balancers handles the incoming request, it only needs the public key associated with the signing key to verify whether the request is valid.
Which security protocol to chose depends on the requirements you have. OAuth is used often for internet applications. WS-Federation and SAML-P are used a lot in enterprise environments.
As far as I see JWT (JSON Web Token) is supported in grails - it seems that this is what you're looking for. Basically you need to separate the authentication server as in this image. Authentication verifies the user/pass being sent and issues a token that is easily parseable without any further access to DB. To only thing that needs to be shared is the key that will be used to decode the incoming JWT. See, how it works.

Java: Access an API that uses SAML authentication

I have a web project that needs to pull some data from a hosted versionone instance. The versionone instance uses SAML authentication for single sign-on.
The single sign-on itself uses a username and pin+one-time password for authentication so it is nearly impossible to hard-code those values into the application.
Is there a way to handle this situation? Can I set something in the header of the request to bypass the single-signon process?
As of release 13.1, VersionOne supports OAuth2 for authentication against the API endpoints. Both the Webserver flow (where the hosted instance POSTs auth tokens to your waiting HTTP server) and the Out-of-band flow (where the hosted instance gives the user a code to copy/paste to the client) are supported.
That may be a better match for your requirements, as the SAML process is difficult to complete without a web browser and user present.
Once the OAuth2 credentials are obtained by the app, it can operate without user intervention. At any time, the user may revoke the app's permissions inside of VersionOne.
With OAuth2, the process is:
Register your app with VersionOne, thus creating a client secret
Configure the app with the client secret data from the registration
Have the app request a permission grant, which sends you to the VersionOne server.
Login to the server as the user you wish the app to act as, and accept the grant.
Copy the grant code back to the app if using the out-of-band flow.
The app contacts the VersionOne instance and exchanges the code for a persistent token.
The app can apply the token as an "Authorization: Bearer " HTTP header to achieve access to the VersionOne endpoint
If the token has expired and the request returns Unauthorized, the client may attempt to refresh the token and try again, without user intervention.
There is some documentation available on the VersionOne community site.
And a few (in-progress) examples in the VersionOne OAuth2 Examples repository
We also have a (beta) HTTP proxy that can run on your app's server, forwarding requests to the VersionOne instance after wrapping them with OAuth2 and SSL.

Categories