I have a three-part question related to JBoss 5 Authentication (in the Web/EJB containers):
Is there a way to propogate an
identity other than the username
that was specified during login? For
example, using the
DatabaseServerLoginModule, I want to
authenticate the user with a
username/password but return the
user's id, and not username, when
ejbContext.getCallerPrincipal() or
httpRequest.getUserPrincipal() is
called.
Even better, I want to make a custom
login module which returns a User
object (probably an entity which was
loaded from the database). However,
even if I wrap that User object up
nicely in a Principal subclass in my
login module, the EJB-layer never
gets that object. Instead, the
EJB-layer always gets a
SimplePrincipal when
getCallerPrincipal is called.
I want to be able to trigger a login
programmatically, as described in
WebAuthentication. However, I need
to do this without knowing the
password. Imagine a customer service
interface where a customer service
agent can login to the application
as an end-user. They would click a
"login-as" button and we should be
able to programmatically log them in
as a user, without ever knowing the
user's password (the customer
service agent is already
authenticated himself). You could
also have this same scenario with
"forgot password" which uses an
alternate login mechanism to
authenticate the user and then
programatically logs them in.
Thanks!
1) Not that familiar with the DatabaseServerLoginModule but shouldn't the user's id also be their username? Usernames should be unique at least?
(Well after reading the rest of your question maybe this is not helpful...)
Answering my own question from two years ago: since the time I wrote this question, we've switched over to Spring Security and found it to be much more flexible than what's available in JBoss alone. My recommendation to anyone looking for a real solution to this problem is to give up on the container-provided authentication and take a good look at Spring Security.
Related
I understand that token based authentication is widely used for microservices, esp, when there is horizontal scaling.
For microservices also, can we use sessions by storing it in database?
The series of requests would be :
First request, HTTPsession is created and session id stored in a database table along with unique
username.
Second request is sent with this session id, and any
microservice instance can serve this request. Server has to verify
this session and user with that of the database record. If sesssionid+username combo is present in database and sessionid is a valid one, then serve the request else redirect to login page.
When logout is clicked, session is invalidated and db record is also removed.
Will this not be a good session management for microservices?
Do Microservices always have to be stateless?
The reason token based authentication is used for microservices, is to avoid having to share session state between the services.
If you specifically refer to an implementation of the javax.servlet.http.HttpSession object, this is normally local to one server (service) and it would take some custom code to reload this based on the session id provided, if at all possible in your particular runtime (don't know what software you are using).
I don't see why your suggestion wouldn't be possible though, but I would carefully consider if it is an absolute requirement. There might be other, simpler, ways to achieve what you want.
One way of doing it would be to issue a token (JWT comes to mind) when logging in, and having the other services simply verify this token and extract the user data from it. This way no lookup of user data is required for authentication after the first login.
If shared state is what you need, I would suggest finding some existing software to handle the session storage. I see that for instance Redis has a solution for session management.
Also you may check out the answers to this question
I know how to retrieve user details if he is logged on, using SecurityContextHolder.
// Some code
UserDetails userDetails =
(UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
So, my question is:
Is it possible to retrieve information about not currently logged user, for example by User Id only?
And how can I update the information about users if they are currently offline?
The one populating your SecurityContext is usually a UserDetailsService, which you have to implement yourself or you take one of the existing ones.
I'm not sure I fully understand your question, but in theory you can simply use your UserDetailsService (or the services it itself uses to load a user), to get all the details you want. So, if you have a JPAUserDetailsService, this will likely call a repository and there's nothing stopping you from using that repository yourself.
What exactly is it that you are trying to do?
I'm using OpenID. How do I make it so that the user stays logged in for a long time even after closing the browser window?
How do I store and get access to the user's User object?
Basically, I guess I just don't really understand how sessions work in Java.
So you actually want like a "Remember me on this computer" option? This is actually unrelated to OpenID part. Here's a language-agnostic way how you can do it:
First create a DB table with at least cookie_id and user_id columns. If necessary also add a cookie_ttl and ip_lock. The column names speaks for itself I guess.
On first-time login (if necessary only with the "Remember me" option checked), generate a long, unique, hard-to-guess key (which is in no way related to the user) which represents the cookie_id and store this in the DB along with the user_id. Store the cookie_id as cookie value of a cookie with known cookie name, e.g. remember. Give the cookie a long lifetime, e.g. one year.
On every request, check if the user is logged in. If not, then check the cookie value cookie_id associated with the cookie name remember. If it is there and it is valid according the DB, then automagically login the user associated with the user_id and postpone the cookie age again and if any, also the cookie_ttl in DB.
In Java/JSP/Servlet terms, make use of HttpServletResponse#addCookie() to add a cookie and HttpServletRequest#getCookies() to get cookies. You can do all the first-time checking in a Filter which listens on the desired recources, e.g. /* or maybe a bit more restricted.
With regard to sessions, you don't need it here. It has a shorter lifetime than you need. Only use it to put the logged-in user or the "found" user when it has a valid remember cookie. This way the Filter can just check its presence in the session and then don't need to check the cookies everytime.
It's after all fairly straight forward. Good luck.
See also:
How to implement "Stay Logged In" when user login in to the web application
How do servlets work? Instantiation, sessions, shared variables and multithreading
Well, the original reason I chose OpenID was so someone else could handle as much of the implementation and security of authentication for me.
After looking into OpenID more, it appears there is something called an "Immediate Request" (http://openid.net/specs/openid-authentication-2_0.html#anchor28).
When requesting authentication, the Relying Party MAY request that the OP not interact with the end user. In this case the OP MUST respond immediately with either an assertion that authentication is successful, or a response indicating that the request cannot be completed without further user interaction.
Because of this I think I could just store the user's openID url in the cookie, and use an immediate request to see if the user is authenticated or not. This way I don't have to do anything with my database, or implement any logic for preventing session hijacking of the long-lived cookie.
This method of doing it seems to be the way OpenID suggests to do it with their Relying Party Best Practices document.
The title tries to explain the scenario:
This customer has a login functionality that allows users with the same name but on different locations (stores).
At the login page the user informs userName, password and the required store.
Using Spring Security (with JPA) I created an UserDetailsService implementation but this interface always receive an userName (and the store was essential to differ from another users).
Giving this situation I have two questions:
How do I inform the spring security about the additional field? (store)
How do I implement an UserDetailsService with this info?
Is that even possible? I've been doing some research but the solutions weren't clear.
Thank you guys, you are the best =D
Your question is not all clear to me. Do you have a unique login for multiple stores? Then you don't need to give the store to your UserDetailsService implementation. I would simply load the user information using its username and if the users are not authorized for all the stores, you could use the GrantedAuthority to define where the users is authorized, e.g. ROLE_STORE_ID1, ROLE_STORE_ID2, etc.
If you have multiple stores where users are not shared, then you could simply create a configurable custom implementation of UserDetailsService, instantiate one per store and uses the correct instance depending on the store the user is accessing.
I hope this will help.
Very basic question.
I have a portal containing several servlets, one of which takes care of logging in (but only as an admin). How do I use HttpSessions between Servlets to know if the admin is signed in?
Thanks in advance!
Whenever your admin users signs in put something like session.setAttribute("admin","true");
check this as session.getAttribute("admin") to see if admin is logged in
set an attribute in session
session.setAttribute("isAdmin",true OR false);
At the login time decide the user type and set it.
I'd store the complete user object in the session.
http://download.oracle.com/javaee/1.3/api/javax/servlet/http/HttpServletRequest.html#getSession()
You can gain access to the session through this method.
If you store the whole user in the session (or the user-id from your database), you can implement a more refined, role-based access later on as your application grows.
greetings