【问题标题】:Spring Security - Invalid property 'principal' of bean class [org.springframework.security.authentication.UsernamePasswordAuthenticationToken]Spring Security - bean类[org.springframework.security.authentication.UsernamePasswordAuthenticationToken]的无效属性'principal'
【发布时间】:2012-09-21 12:42:25
【问题描述】:

我必须为一个项目实现一个自定义的“身份验证提供程序”,但是当我尝试在 JSP 中访问身份验证的对象属性时遇到了麻烦。细节: 我的自定义身份验证提供程序成功创建了一个身份验证对象

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

(这里只写相关代码)

然后,在控制器方法中,我只是显示带有用户名的日志消息(这证明 Authentication 对象已创建并放置在安全上下文中):

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

然后在JSP页面中我想显示用户名使用

<sec:authentication property="principal"/>

但是,这会引发错误 500:

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

我也注意到了

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

不起作用,尽管用户在 Authentication 对象中添加了必要的角色。

我做错了什么吗?身份验证工作正常,我只是无法访问身份验证对象的属性。

非常感谢您,祝您有美好的一天。

【问题讨论】:

  • 你使用什么版本的 Spring Framework 和 Spring Security?
  • 对不起,忘了提 - Spring Framework 3.1.0 和 Spring Security 3.1.0

标签: spring-security principal


【解决方案1】:

您的 AuthenticationProvider 必须返回 UserDetails 对象。

来自 spring 文档 此标记允许访问存储在安全上下文中的当前身份验证对象。它直接在 JSP 中呈现对象的属性。因此,例如,如果 Authentication 的主体属性是 Spring Security 的 UserDetails 对象的实例,那么 using 将呈现当前用户的名称。

【讨论】:

  • Deepak,UsernamePasswordAuthenticationToken实现了Authentication,所以一切都是正确的。唯一的区别是您必须使用 而不是
【解决方案2】:

鉴于我看不出您的情况有什么问题,我认为可能是SPR-8347 错误,该错误已在 Spring 3.1.1 中修复。可以升级吗?

【讨论】:

  • 耶!将 both Spring Security 和 Spring Framework 升级到 3.1.2 就像一个魅力。非常感谢!但是, 问题仍然存在。用户具有必要的角色,但 标记中的片段不显示...
  • 解决了,原来是键盘和椅子之间的错误-我的角色名称末尾有一个“”。
【解决方案3】:

老问题,但我认为我可以帮助其他人。

作为 UsernamePasswordAuthenticationToken 的第一个参数,你可以发送一个用户。

不是传递用户名,而是传递用户本身。但是用户必须是扩展了 org.springframework.security.core.userdetails.UserDetails 的类:

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

查看您使用的方法:

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
    }

现在,在你的 tamplete 中,嗯可以使用这样的东西:

<span class="hidden-sm-down" sec:authentication="principal.email">Email</span>

【讨论】:

    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多