-
Notifications
You must be signed in to change notification settings - Fork 6k
Authentication and Principal arguments in controller functions are null with anonymous principal #4011
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
any update on this? |
Is this an expected behaviour? I am also facing the same "problem". I have a page which I would like to show to both Authenticated and Anonymous users in different way. I have specified "permitAll()" for that url. I was expecting to differentiate between the two in the controller/template. But since Authentication is coming as null, I am not able to. Following is my current configuration. @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/content").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
} Here I am having problems with the URL ending in "/content". |
@renjithgr you can use
in your controller |
I found this issue searching for solutions to the same problem, which seemed like a bug to me as well. I eventually traced all the way into SecurityContextHolderAwareRequestWrapper and found this: /**
* Obtain the current active <code>Authentication</code>
*
* @return the authentication object or <code>null</code>
*/
private Authentication getAuthentication() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!trustResolver.isAnonymous(auth)) {
return auth;
}
return null;
} So I guess it's intentional, though the docs don't seem to give much in the way of reasoning. On a hunch I threw a custom trust resolver into the context: @Bean
public AuthenticationTrustResolver trustResolver() {
return new AuthenticationTrustResolver() {
@Override
public boolean isRememberMe(final Authentication authentication) {
return false;
}
@Override
public boolean isAnonymous(final Authentication authentication) {
return false;
}
};
} This worked, and now I can get my Thanks! |
i experienced this issue too |
For everybody landing here, because they can't inject
For me the problem began when I switched to a custom |
( How does the triage process work? ) As gregb pointed out 2 years ago, and from the javadoc, this is deliberate. Why does the SecurityContextHolder contain an anonymous Authentication instance, but it's not injected into the controller parameter? Yes, there's a workaround, but it's ugly. Would love to have it fixed - springboot 2.1.9? Pleeeease.... |
Solution for injecting |
This is addressed in spring-projects/spring-framework#25981. In Spring Web 5.3.1, using Note also that you can get the As for the question about the deliberate exclusion of anonymous users in the wrapper class, you can see Luke Taylor and Rob Winch's answers in two older issues: #1333 and #2232. |
But this does not address the initial issue of resolving anonymous Authentication in controller. What if I don't need a Principal but an Authentication object, how do I get one as a controller parameter? As Authentication class extends Principal I can't even create my custom resolver as it will be overridden by default spring principal argument resolver. I know I can use |
Hi, @minogin. I'd recommend using You can do: public String myMethod(@CurrentSecurityContext SecurityContext context) {
Authentication authentication = context.getAuthentication();
// ...
} |
Unfortunately this does not work for me as See
While custom argument resolvers are added after So I wonder how it works for you. Do I miss something? Is there a way to disable this standard behaviour? |
You're right, @minogin. I removed my other suggestions in my earlier comment to alleviate any confusion. |
A workaround (maybe not the best one) is to make Kotlin code:
|
Summary
When using anonymous user in security and trying to inject the Authentication or Principal to a method in a RestController they are null. If a real user is authenticated then it will work.
Actual Behavior
Getting null in Authentication and Principal when anonymous user is logged and working with real user. When using
SecurityContextHolder.getContext().getAuthentication()
we are getting the right user (anonymous).Expected Behavior
The Principal and the Authentication should be the same as returned from:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
.Configuration
Version
Spring boot 1.3.7
Sample
Working code:
Not working code (getting null)
The text was updated successfully, but these errors were encountered: