Spring Security - Invalid property 'principal' of bean class [org.springframework.security.authentication.UsernamePasswordAuthenticationToken]

StackOverflow https://stackoverflow.com/questions/12530837

  •  03-07-2021
  •  | 
  •  

سؤال

I had to implement a custom "authentication provider" for a project, but I ran into troubles when trying to acces the Authentication's object properties in JSP. Details: My custom authentication provider successfully creates an Authentication object

Authentication auth = new UsernamePasswordAuthenticationToken(username, password, getAuthorities(userRoles));
log.info("User is authenticated");
return auth;

(Only relevant code here)

Then, in the controller method, I just display a log message with the username (this proves that the Authentication object is created and placed in the security context):

Authentication auth = SecurityContextHolder.getContext().getAuthentication();        
log.info("Welcoming user " + auth.getPrincipal());

Then in the JSP page I want to display the user name using

<sec:authentication property="principal"/>

However, this raises an error 500:

org.springframework.beans.NotReadablePropertyException: Invalid property 'principal' of bean class [org.springframework.security.authentication.UsernamePasswordAuthenticationToken]: Bean property 'principal' is not readable...

I also noticed that

<sec:authorize ifAnyGranted="role">...

is not working, although the user has the necessary roles added in the Authentication object.

Is there something I'm doing wrong? The authentication works fine, I just can't access the authentication object's properties.

Thank you very much and have a good day.

هل كانت مفيدة؟

المحلول

Given that I can't see anything wrong with your case, I think it can be SPR-8347 bug, which is fixed in Spring 3.1.1. Can you do an upgrade?

نصائح أخرى

your AuthenticationProvider must return UserDetails object.

From spring documentation This tag allows access to the current Authentication object stored in the security context. It renders a property of the object directly in the JSP. So, for example, if the principal property of the Authentication is an instance of Spring Security's UserDetails object, then using will render the name of the current user.

Old question, but I think that I can help other folks.

As the first parameter of UsernamePasswordAuthenticationToken you may send a User.

Instead of passing the username, pass the user itself. But the user must be a class that extends org.springframework.security.core.userdetails.UserDetails:

Authentication auth = new UsernamePasswordAuthenticationToken(user, password, getAuthorities(userRoles));
log.info("User is authenticated");
return auth;

See the method that you was using:

public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
            Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        super.setAuthenticated(true); // must use super, as we override
    }

Now, in yout tamplete, um can use something like this:

<span class="hidden-sm-down" sec:authentication="principal.email">Email</span>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top