I'm running Glassfish 3.0 and I'm implementing JDBCRealm for login authentication. The username and roles are saved in a table called usertable. The authentication is working as expected.
But the problem is now when the user logs in, how can I retrieve the username of the logged in user in the application?
PS: I'm implementing JSF page and Managed Bean
In JSF, you can retrieve the current Principal associated with the request and hence, the current session, using the ExternalContext object, which can be retrieved from the FacesContext. The Principal associated with the request is accessible from the ExternalContext using the getUserPrincipal() method:
FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
The above invocation can be done in a JSF managed bean. You can invoke the getName() method on the Principal object to retrieve the name of the user as a String.
Note that, it possible for you to obtain a Principal instance that references the Anonymous user, if you are retrieving the Principal before authentication, or if the authentication scheme does not protect the entire site.
Request.getRemoteUser or Request.getUserPrincipal, independent of the realm you use for authentication, so if you use a File realm for testing and a JDBC realm for production it will work in both cases. By the way, if you use JDBCRealm also have a look at FlexibleJDBCRealm.
Your authenticate method should return a java.security.Principal which will contain the name.
http://download.oracle.com/javase/1.4.2/docs/api/java/security/Principal.html
Related
I'm trying to get logged in users' details who are connected via websocket on Spring Boot 2. To do this, I'm currently using SimpUserRegistry to find a list of connected SimpUsers.
Since Spring Boot 2.4, I noticed the SimpUser class has a getPrincipal() method that returns a generic Principal object. As each user is supposed to login via Spring Security's mechanisms, I thought I was able to cast it to Spring Security's UserDetails to get the logged in user , but I realize it wasn't the case.
Does anyone know how I can make use of getPrincipal or other ways to get logged in userDetails?
First of all, let's make it clear that, to use getPrincipal() with websocket, you have to implement websocket authentication and authorization through Interceptor (as far as I know SpringSecurity doesn't do this automatically).
After doing the above correctly, you can now use the getPrincipal () method. It will return The identity of the principal being authenticated (maybe Username, email,...)
You can use code that looks like this:
#MessageMapping("/test")
public void doSomething(#Payload AppMessage appMessage, Principal principal) {
String username = principal.getName();
// find userDetail with username here
}
I have a Spring REST-API which is secured by SpringSecurity.
I have different ways to authenticate in that application.
Customer (db)
Employees (ldap)
Other Applications/Services (inMemory)
Each of these are covered by a different authentication provider, which properly assigns the access roles. (Works)
However I need to know which authentication provider was used to authenticate the user, so I can write it to the logs, history...
User CUSTOMER/max.pain created a new entry.
And of course the username does not really contain that prefix, neither in the db, nor in ldap.
I considered adding a special role based on the authentication provider used, but extracting that information over and over is annoying and probably has bad performance and might cause problems in the future. (user.getGrantedAuthorities().findStartingWith("AP_"))
I also tried using org.springframework.security.config.annotation.SecurityConfigurerAdapter.addObjectPostProcessor(ObjectPostProcessor<?>) but i cannot use it to wrap the AuthenticationProvider with a custom AuthenticationProvider class, because it requires the use the same class for whatever reason.
Is there an inbuild method I could use to achieve that or do I have to use a custom implementation/configuration?
Prozess steps:
Login: EMPLOYEE/always.calm
Don't check CUSTOMER AuthenticationProvider
Check EMPLOYEE AuthenticationProvider
Don't check SERVICE AuthenticationProvider
authentication.getPrincipal().getAP() = EMPLOYEE
I'm trying to access the HttpSession object (or similar API that let me fetch session attributes) from inside of a Google Cloud Endpoints backend method...
Reading this answer I've learn that I can inject a HttpRequest object as a parameter.
What I'm trying to do is retrieve a facebook access token previously stored by a Servlet.
Within the Development Web Server I can retrieve the HttpSession and get the desired attribute:
#ApiMethod
public MyResponse getResponse(HttpServletRequest req) {
String accessToken = (String) req.getSession().getAttribute("accessToken");
}
But, once I deploy my application to GAE, the retrieved access token is always null.
So is there a way to recover session attributes from inside api methods?
And if there isn't, how can I retrieve my access token from someplace else? Answers and comments in the mentioned question suggests the use of the data store, but I really can't think of a good natural candidate for a key... As far as GAE authentication mechanism is concerned my users aren't even logged in, I don't know how to retrieve the access_token of the current user from the Datastore / memcached or any other mechanism.
I've filed a feature request to support sessions in production, as I can confirm it's not working right now.
For now, I recommend you continue passing the access token on subsequent requests in a header. Header information is similarly available through the injected HttpServletRequest.
I have a spring-mvc application that currently has two channels - web application and a REST service. Both have user's http session and I can easily get the "current user" in my service classes.
Now I need to develop another REST service where there are no http sessions and the current user depends on a request parameter. So the controller would read that request parameter and would find the current user.
Now I either need to:
1. modify my service layer methods to accept current user as parameter
or
2. just modify the class that gets the current user from the http session.
I also have the requirement to create an audit log and I'm going to use Spring AOP for that. The Aspect will need access to the "current user" too. So option #1 probably won't work for me and I will go with #2.
For option #2 I'll create an interceptor that will put the current user in a ThreadLocal variable. The controller for the new REST service will do the same and then in my service layer and in the audit log aspect I can get the current user from there.
I haven't done anything like this before and was wondering if there is a better approach. Or what kind of issues I should expect with this approach.
I will appreciate any comments and ideas.
Oz
Here is how I currently get the current user:
#Override
public User getCurrentUser()
{
Authentication currentUser = getAuthentication();
return userService.getByLoginName(currentUser.getName());
}
protected Authentication getAuthentication()
{
return SecurityContextHolder.getContext().getAuthentication();
}
I think a simple way to do what you need is to configure a servlet filter for your new REST webservice to populate the SecurityContextHolder with an Authentication object build from request parameters.
You can read this : http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e2171 for more details.
With this solution you don't need to modify the code to retrieve the current user. (note that the SecurityContextHolder is already using a ThreadLocal to store the SecurityContext and so the Authentication)
Summary
How do you get the session of a web service client using spring web services and spring security?
Details
After submitting
<form method="POST" action="<c:url value="/j_spring_security_check" />">...</form>
I've noticed that you can:
public class MyUserDetailsService implements UserDetailsService {}
Which will allow you to override methods like loadUserByUsername(String username) therefore being able to retrieve the submitted username and do a database lookup to return a user object.
The issue I have, however, is that I'm unsure where SecurityContextHolder gets set. I'm able to get the user object by using this line of code:
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
But I'm not sure how it gets set in the first place. I would like to know the flow after submitting the above-mentioned form so that I can identify how SecurityContextHolder gets set.
The reason why I want to know this is because I want to use it as a "session" for web service client authentication instead of having the client resubmit credentials with every request.
Spring Version: 3.0.2.RELEASE
/j_spring_security_check is handled by the UsernamePasswordAuthenticationFilter which extends AbstractAuthenticationFilter. The security context is set in the latter's successfulAuthentication method.
However, web-service clients are usually stateless and would be more likely to use something like Basic authentication with a shared secret. I'm not sure there would be much benefit in rolling your own session system based on the security context contents. If you are worried about performance then you could use a cache of authentication information on the server.