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

Daniel Platon picture Daniel Platon · Sep 21, 2012 · Viewed 7.7k times · Source

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.

Answer

Deepak picture Deepak · Sep 21, 2012

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.