How to authenticate users in Java(REST) app? - java

I have some java server application and some WEB interface(jQuery). For REST services i'm using Jersey implementation. I can easily sent JSON to the server from WEB page and vice versa.
Example of my REST service:
#Path("/users")
public class User {
#POST
#Path("/login")
#Consumes(MediaType.APPLICATION_JSON)
public Response authUser(User user) {
//code
}
}
But there is one problem. How can I auth users?
For example, i have some private resources: when user in not log in, he can't see it resource/web page, but when he logined(enter correct name and password) he can see it resource.
I didn't use sping application. I have googled a lot of time but I didn't find easy examples, then i tried to read Jose's Sandoval book "RESTful Java Web Services", in "Security" section a lot of useful information but there isn't examples.
Could you please help me?

There are different ways to approach this I believe. One way is that when the user authenticates, you send him back a token [which expires after some time] and he then passes back that token in subsequent calls.
Save the token to a file or db. In subsequent requests that come from client , compare token timestamp and value.
Once that token expires he has to re-authenticate.

Related

log out from Oauth2 server AND from all clients

We have a java web app, which contains a lot of wars. We have an Oauth2 server(written by us) and we will have a lot clients( around 8). All of this will be under the same domain. Except of this we have another app( running on completely different tomcat. There a Liferay is used). The idea is that that the user will use them as they are using one app and they should not see big difference.
This is way now what I need is that when I log out from one place in some way to say the oauth2 server and all other clients to log out, too.
Because for client should be : I already logged out why in some parts I'm still logged in?
Currently I'm not sure how to do it.
And to a lot of places I read that normally this is not the practice.
Can you give me hints and explain me from where I can start? Maybe to use Oauth2 in my case in not the best choice?
For your requirement, you can implement OAuth2 using JDBC Token Store from Spring Security. For this to work once user logs out, all client should invoke your Delete token API where you can remove the Access Token
#FrameworkEndpoint
public class RevokeTokenEndpoint {
#Resource(name = "tokenServices")
ConsumerTokenServices tokenServices;
#RequestMapping(method = RequestMethod.DELETE, value = "/oauth/token")
#ResponseBody
public void revokeToken(HttpServletRequest request) {
//Delete the Token
}
}
Also, you should delete the refresh token.This way, the token would be invalidated once user logs-out and subsequent client can no longer use the same token

Add authentication to GAE Java endpoints

I am generating some endpoints and it works correctly, however, I would like to keep one session per client so I do not have to send the request by mail and password, but I am not sure of doing it.
This is an example of one of my endpoints
#Api(name = "test")
public class MyApi {
#ApiMethod(name = "printHi", httpMethod = "POST")
public Message imprimirHola(Input input) {
Message message = new Message();
if(datosCorrectos(input.getMail(), input.getPassword()))
message.setMessage("Hi");
else
message.setMessage("authentication failed");
return message;
}
}
After doing some research in the topic you have issues with, I have found the following information that can be useful for what you are trying to achieve.
Google Cloud Platform offers the Cloud Endpoints service, which has some available frameworks for user authentication. You can find detailed information and procedures about that in the documentation but, in short, you can use Firebase Auth, Auth0 or Google Accounts to authenticate a user against your endpoints (this link will help you decide which option suits you better).
However, in order to operate with one of those options, you will need that your API is managed by Cloud Endpoints, so you will have to follow this walkthrough to Add API Management to your API using OpenAPI.
Finally, here you have a working example on how to that using Java.
I know it is a lot of information, but I think you will be able to solve the authentication issue with your Java API just by reading more detailed information in this last documentation page, and move step by step in the "Getting Started" dropdown menu in the left of this page.

Securing jax-rs with OAuth

I have following problem:
I have JAX-RS service which has a get operation:
#Path("/unsecure/")
#Produces("application/json")
public class MyUnsecureService {
public MyUnsecureService() {
}
#GET
#Path("/get/{id}")
#Produces("application/json")
public User get(#PathParam("id") String id) {
return User.get(id);
}
}
now, I'm going to open this API for mobile devices and I need authentication and authorization mechanism to access the API.
My problem is that I have trusted apps (internal jobs, a website which runs on my hosting) which should be able to expose this API as they want, with no limitation, and mobile devices, which should be able to expose this API only if they have a token, formed using real User's encrypted login/pass, which can be used on service-side to determine:
If the request to that method is allowed.
If the parameters are correct (so, the user can't get other user's info).
Is this possible to do using OAuth1 or OAuth2?
This is a very valid question to raise.
You might want to have a look at Oz (backgroud), which AFAIU will go a long way towards your use cases. Personally, I have interest to solve the issue for Java and track Eran's work with Java implementations ( jiron, hawkj ). To finally do Oz (or something like it) in Java.
Much is not ripe for publishing right now, but get in touch for details if you like.
Specific problem with JAX-RS right now seems to be SecurityContext.
The answer is found:
Using Client Credentials and Resource Owner authorization grants, which are implemented in OAuth2 implementation of Apache CXF.

Jersey-request for authentication

I have a working JavaEE 6 web application on Glassfish, this application already has a JSF frontend and has its authentication mechanism((Using CDI and annotation based security) So there is a login screen, user enters username password, press login button and Java EE authentication process begins.
Now I want to "also" expose some of my service classes as a REST service (I will use Jersey probably), so it can also be reached from a mobile device. But what worries me is the login part.
I will use the exact same existing authentication But now I want my application will get this credentials from a Rest Request but not from the login screen. And then continue using the existing validation methods which already exists(check username password from DB,,etc)
I kinda got lost how can I do this, I think I need to use one of these filters to intercept the request and get the username password but not sure how and which one? Or I dont need anything like this?
You can protect the REST service the same way you protect the REST service, for example:
#Path("/foo")
#RolesAllowed({"admin", "customer"})
public class Foo {
#GET
#Produces("text/plain")
#RolesAllows("admin")
public void adminOnly() {}
public void adminOrCustomer() {}
}
I guess you already have roles and mappings for them so just use the same roles you got, the application server will take care of the rest.

Designing RESTful login service

I went through a similar question here. But I am yet not clear over concepts. Here is my scenario...
My client (a mobile device app) has a login screen to enter username, password. After submission, he should see the list of books in the database plus the list of books subscribed by that user.
I am having a /LoginService which accepts username, password & checks a mysql database for credential validation. Only after authorization....I have a /BookService ; GET on which returns all the books in database.
Should I use GET, POST or PUT on my loginservice ? Since a login request is a read-only operation, I should use GET - but this sounds stupid for browser(as the submitted data is visible).
What are accesstokens (mentioned in the linked answer above), and how to generate them using Java ? I am using Jersey for development. Are they a secure way of authorization ?
Thanks !
As far as I understand you are trying to implement stetefull communication between client and server. So you login with first request and then use some kind of token to make further requests.
Generally I can recommend you to have stateless communication. This means, that you authenticate and authorize each request. In this scenario you don't need LoginRestService. Important points here are:
Client can provide userName and password through HTTP Headers (non-standard, something like UserName: user and Password: secret).
At the server side you can use
Use AOP: just wrap you BooksService with AuthAdvice (which you should write yourself). In advise you access somehow (with Jersey functionality) HTTP request, take correspondent headers from it, authenticate and authorize user (that you load from DB), put user in ThreadLocal (so that it would be available to the rest of your app) if needed and just invoke correspondent method or throw exception if something wrong with credentials.
Use Jersey functionality: (sorry I'm not very familliar with Jersey, I'm using CXF, but conceptually it should be the same) just create some kind of AuthHendler and put it in request pre-processing pipeline. In this handler you need tho make exactly the same as in AuthAdvice
Now each of your request would be authenticated and authorized when it reaches BooksService. Generally stateless implementation is much better for scalability.
If you want to go statefull way, than you can just use HttpSession. LoginService.login() should be POST request because you actually making some side-effects at the server. Service will perform authentication of your user according to provided username and password and put loaded User object to session. At this point, the server side session is created and client has session ID in the cookies. So further requests should automatically send it to the server. In order to authorize requests to BooksService you still need some kind of Advice of Handler (see stateless solution). The only difference: this time user is taken from the HttpSession (you should check that you are logged in!).
Update: And use HTTPS! :)
I've got nothing to dispute in Easy Angel's answer, but got the impression you'd like some additional comment on the concepts too.
The problem is clearer if you think in terms of resources rather than services. Think of your proposed login as generating a new authorization resource, rather than querying a login service. Then you see that POST makes perfect sense.
The authorization token would be a key for your user into the session object (as explained in EA's answer). You'd probably want to generate it by concatenating some information that uniquely identifies that user and hashing it. I certainly agree that a stateless authentication method would be preferable, if you're aiming to get all the benefits of REST.
Use what is available in HTTP: HTTP AUTH over SSL.
Protect all your resources with HTTP AUTH and the browser will take care of providing a login for the user.
If you need session information on top of that, use cookies or a session parameter.
Cookies were made for exactly these kinds of purposes and usually work well.

Categories