Reputation: 652
I'm developing a web application that use Spring Security for authentication of users. I know that i can get the logged in user in this way:
public class SecurityUtil {
public static User getCurrentUser() {
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
}
}
And in this way works fine. The question is: which is the best way to access this value? I will make some example:
1.User declared as variable in the controller:
public class FooController {
@Autowired
private FooService fooService;
private User u = SecurityUtil.getCurrentUser();
@RequestMapping(...)
public void control() {
fooService.doSomething(u);
}
}
2.User as parameter passed to the service:
public class FooController {
@Autowired
private FooService fooService;
public void control() {
fooService.doSomething(SecurityUtil.getCurrentUser());
}
}
3.User accessed in the service:
public class FooService {
public void doSomething() {
SecurityUtil.getCurrentUser();
//Do something
}
}
Are all this examples valid? Can I use anyone of them indistinctly? There are some drawbacks of which I should be aware of?
Upvotes: 0
Views: 408
Reputation: 9505
Example 1
Example 1 is not usable since Spring bean by default is singleton, which mean that when the FooController
is created, the User
variable is not assigned correctly or it is null
. As other answer point out, it is also not thread safe.
Example 2
Example 2 is my recommended way to do it, it is more testable in unit test. But I would recommend use the following example (Spring 3), refer doc here:
@RequestMapping(method = RequestMethod.GET)
public String index(Model m, HttpSession session, Principal principal) {
// principal.getName() return username
return "XYZ";
}
Example 3
Example 3 is usable, but not easily testable and hard to maintain.
Upvotes: 2
Reputation: 13114
Example 1 is not thread-safe. In general your service beans should be stateless.
With example 3, it depends on how you are invoking the FooService
from your controller. If this invocation crosses application boundaries then you need to ensure the Spring SecurityContext
propagates with the invocation for it to work.
Example two should be fine in all cases but passing the current user into the service method doesn't seem like correct separation of concerns.
Upvotes: 0