Jersey-request for authentication - java

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.

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

How to authenticate users in Java(REST) app?

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.

How can I store information in the context of a web service?

I use a web service which is responsible for user logins. If a login is successful, a token should be generated.
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/login")
public String login(#QueryParam("userName") String name,
#QueryParam("password") String password) {
//Spring Securtity Check
HttpResponse r =loginResponse(name,password);
String s = r.getFirstHeader("Location").toString();
boolean isError = s.contains("login_error");
if(!isError){
//TODO store Token in the application context
MD5 token = new MD5(name+System.currentTimeMillis());
return "token:"+token.getMD5();
}
return "fail";
}
I would like to store the token in the application context, but I don't know how. The token should exist as long as the server application is running. Does the web service have its own application context? Should I use some kind of HTTP servlet to store the information?
store it in memcached, using it you can apply some expiration policy, and also when you have more than one server, it will be an problem to store it in the local memory, store it in global cache like memcached is more apropariate.
I don't quite understand what you call the application context.
Is it ServletContext? You can get it in Jersey using the #Context annotation: #Context ServletContext. You can get is either as a field in your resource, or as a parameter to your method.
The ServletContext is up, while servlet is up. It may be removed by the servlet container depending on its configuration.
Btw. your design is really really bad and insecure. You use GET for login operation and pass both username and password on the url. This means few things:
GET requests can be cached by intermediaries. Do you want it to happen?
Everybody will see password in url. Even if you use SSL, password will be still in url, seen to everyone.
URL is often logged, both by client, servers and intermediaries. You really, really, really don't want the password to be logged.
I'm voting your question up, since it's a great example of a bad design for login.

Seam security with externally-orchestrated SSO

I have an application deployed on WebLogic 10.3.2 (11g), in which the user logs in through SSO. In other words, if the user is not logged in, he is redirected to SSO, where he logs in, and then is redirected back to the application. The whole redirection takes place by an the Oracle HTTP Server (a modified apache), which makes sure that only SSO-authenticated users can see the applciation.
So, when the user finally sees the application, he is already logged in.
Is there a way to use Seam security with this scenario? What I would like is to use the roles of the Subject to restrict access to certain pages and components.
A way I thought of, but for which I am not sure, is to use the subject that is populated by the SSO authentication provider of WebLogic, and use it to populate the Identity component of Seam. That would take place in the authentication method, which will always return true (since the user is already logged in). Inside the method, the credentials and roles of the Subject will be "transfered" inside the Seam identity.
Is this feasible at all?
Cheers!
You could write your own authenticate method, or override the Identity class and the login() method to achieve this. I've done something similar with a reverse proxy that performed our authentication. In the scenario, the proxy sent back the user ID of the authenticated user and all the groups they were a member of as header values. I wrote a filter to intercept the headers and then used my custom Identity class to do the rest.

JAXWS and sessions

I'm fairly new to writing web services. I'm working on a SOAP service using JAXWS. I'd like to be able to have users log-in and in my service know which user is issuing a command. In other words, have some session handling.
One way I've seen to do this is to use cookies and access the HTTP layer from my web service. However, this puts a dependency on using HTTP as the transport layer (I'm aware HTTP is almost always the transport layer but I'm a purist).
Is there a better approach which keeps the service layer unaware of the transport layer? Is there some way I can accomplish this with servlet filters? I'd like the answer to be as framework agnostic as possible.
I'm working on a SOAP service using JAXWS. I'd like to be able to have users log-in and in my service know which user is issuing a command. In other words, have some session handling.
Conventional Web services are stateless in nature, there is no session handling in web services (which has by the say nothing to do with identifying the caller).
If you want to require your users to be authenticated to call a service, the traditional approach is to:
Expose an "authentication" web service (passing user credentials) that returns an authentication token.
Have the users call this authentication first.
Have the users pass the token in a custom header on subsequent calls of "business" web services.
On the server side:
Reject any call that doesn't contain a valid token.
Invalidate tokens after some time of inactivity
You can implement a custom solution for this approach (this is a highly interoperable solution). Or you can use WS-Security/UsernameTokens that provides something similar out of the box. WS-Security is a standard (Metro implements it), it isn't "framework" specific.
As you mention, servlet filters can provide the basis of solution. Use a filter to store the current session details (e.g. the session context Map) in a threadLocal storage. This is implemented as your application class, so is transport agnostic. Your service simply uses a static method to fetch the current context, unaware of where it came from.
E.g.
class ServiceSessionContext
{
static ThreadLocal<Map> local = new ThreadLocal<Map>();
// context set by the transport layer, e.g. servlet filter
static public void setContext(Map map)
{
local.put(map);
}
// called when request is complete
static public void clearContext()
{
local.put(null);
}
// context fetched by the service
static public Map getContext()
{
return local.get();
}
}

Categories