When using Spring Security, what is the proper way to obtain current username (i.e. SecurityContext) information in a bean?
If you are using Spring 3, the easiest way is:
@RequestMapping(method = RequestMethod.GET)
public ModelAndView showResults(final HttpServletRequest request, Principal principal) {
final String currentUser = principal.getName();
}
Getting the current logged in user name when using Spring Security
What you need is called @AuthenticationPrincipal
.
You can inject it in controller method like this:
@GetMapping("/")
public void get(@AuthinticationPrincipal User user){ ... }
Here is documentation
Alternatively, you can create your own annotation and custom argument resolver, and inject whatever you want.
Getting user information from the current session on Spring?
The only reason that you would get anonymousUser in the security context is if you are not authenticated. Try adding .anyRequest().authenticated()
right after hasRole("USER").
in your SecurityConfig and then you should see the principal in SecurityContextHolder.getContext().getAuthentication()
. This will continue to work with the methods you've specified as permitAll()
.
Also, just an observation, but your url matcher in your config is on /home
and your controller specifies a GetMapping of /Home
.
Spring Security - get current user fields from database
The JDBC service you defined in the Spring Security configuration will only fetch username, password and enabled status using the users-by-username-query
query and username's authorities using the authorities-by-username-query
query. This means that any extra attributes will not be mapped to the user principal object which will be created to populate the security context.
One way to get all information of your user is to create custom implementation of UserDetailsService
which will be able to retrieve user data including all of its custom attributes. Here is an example of this approach (it assumes that you are using JPA/Hibernate for your data layer):
Entity
@Entity
@Table(name="users")
public class User implements UserDetails {
private BigDecimal balance;
// Other properties omitted ...
// Getters and setters omitted ...
// Implementation of UserDetails methods omitted ...
}
UserService
Service responsible for loading the user information. Note that in real world you should probably have separate DAO querying users, program against interfaces, etc. This example is deliberately kept as short as possible.
@Service
public class UserService implements UserDetailsService {
@Autowired
private SessionFactory sessionFactory;
@Override
public User loadUserByUsername(String username) throws UsernameNotFoundException {
Query query = sessionFactory.getCurrentSession().createQuery("FROM User u WHERE u.username = :username");
query.setParameter("username", username);
User user = (User) query.uniqueResult();
if (user == null) {
throw new UsernameNotFoundException("User with username '" + username + "' does not exist.");
}
return user;
}
}
Configuration
Create AuthenticationProvider
bean and supply your custom user service as its property.
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userService" />
<!-- Other required properties ... -->
</bean>
Controller
You can access the current user and its properties in the controller using:
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
BigDecimal balance = user.getBalance();
As a final remark, please note that this is not 100% working copy and paste solution to your problem, rather a demonstration of the approach you can take to achive the desired result. I recommend looking through the documentation of core classes/interfaces such as AuthenticationProvider
, UserDetailsService
, UserDetails
, and Spring Security guides for more details.
how to get current user in spring security integrated with cas?
Found the problem! I was going to use my own Access Control system, so I commented filters who where responsible for checking user's roles to access URLs. Apparently if I don't intercept URLs, spring security's context won't be accessible through that request (or at least it seems like that! I am not a big fan of Documents, so I try out codes and when I get an exception, I try to guess the reason! I really should stop doing that :| but anyway now that I intercept URLs, SecurityContextHolder.getContext().getAuthentication() doesn't return null anymore :) )
Related Topics
Execute Method on Startup in Spring
Using Generics in Spring Data JPA Repositories
Why Do I Get Java.Lang.Abstractmethoderror When Trying to Load a Blob in the Db
Get List of JSON Objects with Spring Resttemplate
Splitting String with Pipe Character ("|")
How to Launch a Completely Independent Process from a Java Program
How to Populate a Listview in Javafx Using Custom Objects
Printing a Java Inputstream from a Process
Hibernate, @Sequencegenerator and Allocationsize
Java 8's Streams: Why Parallel Stream Is Slower
Passing Values Between Jframes
Data Access Object (Dao) in Java
How to Have 2 Jvms Talk to One Another