【问题标题】:Spring Security cannot retreieve Currently authenticated userSpring Security 无法检索当前经过身份验证的用户
【发布时间】:2014-12-20 07:47:46
【问题描述】:

我正在开发一个使用 Spring-Security 的 Spring-MVC 应用程序。我需要获取当前经过身份验证的用户对象,以便可以使用 setUser() 方法。但是该方法返回 null,程序似乎因空指针异常而崩溃。请看一下代码。我已经调试了+try-catch,它没有返回用户。

调用 getCurrentlyAuthenticatedUser() 会引发异常。当我检查时,它说身份验证为空。

我已经通过实现接口 UserDetails 和 UserDetailsS​​ervice 来实现 Spring-Security。

人物类:

@Entity
@Table(name="person")
public class Person implements UserDetails{

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "person_seq_gen")
    @SequenceGenerator(name = "person_seq_gen",sequenceName = "person_seq")
    private int id;


    @Column(name = "username")
    private String username;


    @Column(name = "password")
    private String password;

 @Transient
    private final String PERMISSION_PREFIX = "ROLE_USER";
    @Transient
    private List<GrantedAuthority> authorities;

    @Transient
    private String role;

@OneToMany(cascade = CascadeType.ALL,mappedBy = "person1")
  private Set<Notes> notes1;

    public Set<Notes> getNotes1() {
        return notes1;
    }

    public void setNotes1(Set<Notes> notes1) {
        this.notes1 = notes1;
    }
}

登录服务实现:

@Transactional
@Service("userDetailsService")
public class LoginServiceImpl implements UserDetailsService{

    @Autowired private PersonDAO personDAO;
    @Autowired private Assembler assembler;

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
        Person person = personDAO.findPersonByUsername(username);

        return assembler.buildUserFromUserEntity(person);
    }
}

汇编类:

@Service("汇编器")

public class Assembler {
    @Transactional(readOnly = true)
    User buildUserFromUserEntity(Person userEntity){
        String username = userEntity.getUsername();
        String password = userEntity.getPassword();

        // Long id = userEntity.getId();
        boolean enabled = userEntity.isActive();
        boolean accountNonExpired = userEntity.isAccountNonExpired();
        boolean credentialsNonExpired = userEntity.isCredentialsNonExpired();
        boolean accountNonLocked = userEntity.isAccountNonLocked();

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        User user = new User(username,password,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,authorities);
        return  user;
        }
}

// 我在 getPrincipal 的以下方法中遇到错误 PersonServiceImpl :

@Service
public class PersonServiceImpl implements PersonService {

    private PersonDAO personDAO;
 @Override
    public Person getCurrentlyAuthenticatedUser() throws Exception{
        Authentication a = SecurityContextHolder.getContext().getAuthentication();
        Person currentUser = (Person) a.getPrincipal();
        if(currentUser == null){
            throw new Exception("No authenticated user retrieved");
        }else {
            System.out.println("We have currently authenticated user");
            return currentUser;
        }
    }

Spring Security-xml

    <import resource="servlet-context.xml" />

    <!-- Global Security settings -->
    <security:global-method-security pre-post-annotations="enabled" />

    <security:http pattern="/" security="none" />

    <security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
         <security:port-mappings>
        <security:port-mapping http="80" https="443"/>

    </security:port-mappings>
           <security:session-management session-fixation-protection="migrateSession" invalid-session-url="/invalidSession.html">
            <security:concurrency-control max-sessions="3" error-if-maximum-exceeded="true" expired-url="/sessionExpired.html"/>
        </security:session-management>
           <security:form-login login-page="/login" default-target-url="/note/add" always-use-default-target="true" authentication-failure-url="/login?error"/>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="LoginServiceImpl" />

    </security:authentication-manager>

    <beans:bean id="daoAuthenticationProvider"
                class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                <beans:property name="userDetailsService" ref="LoginServiceImpl"/>
    </beans:bean>


</beans>

【问题讨论】:

  • 请给出相关信息:崩溃:异常+stacktrace,方法返回null什么方法,它不返回用户什么调用不返回信息...
  • @Orici 提出这个问题表明你没有做功课,也没有做任何研究工作。我谦虚而友善的建议是,请从基础开始,先了解它的工作原理,否则你会伤害自己并开始说 spring 和 java 很烂,只有 rails 或 node 可以拯救你。
  • @SergeBallesta :我已经编辑了我的帖子以包含崩溃的函数 getCurrentlyAuthenticatedUser()。我有自己的 try-catch 块,异常读取 Authentication is null。
  • @Orici 很明显,您的身份验证无法正常工作,您必须确保在调用 SecurityContextHolder.getContext().getAuthentication() 时获得身份验证实例

标签: spring-mvc spring-security


【解决方案1】:

这仍然不是一个真正的答案,但太长了,无法放在评论中。

在使用从其他方法返回的对象之前,您永远不会测试它们是否不为空。我认为最可能的错误是 SecurityContextHolder.getContext().getAuthentication(); 返回 null 导致下一行出现 NPE。如果这是真的,那意味着您的问题在于 Spring 安全性的配置。但是没看到豆子userDetailsService就不能多说。您说您实现了 userDetail 和 UserDetailsS​​ervice,但没有说明如何实现。

我建议您删除 remember_me,只要您没有可用的基本配置,即:

  • 您必须先登录才能访问受保护的页面
  • 你可以在SecurityContextHolder.getContext().getAuthentication()找到登录的用户

一旦成功,您将添加更多功能。否则,将很难找到问题的原因。

编辑:

你说错误发生在Person currentUser = (Person) a.getPrincipal(); 行。现在很清楚,在上一行

Authentication a = SecurityContextHolder.getContext().getAuthentication();

getAuthentication() 返回空值。这意味着对于 Spring 安全性,当前没有经过身份验证的用户。

【讨论】:

  • 感谢您的帖子。我将在星期一更新代码,因为我已经在家了。 UserDetails 和 userdetailsS​​ervices 的实现比较常见,都是一样的,所以我没有上传。仅仅一个评论就足够了。我还发现一个教程提到了如何在服务中实现 Userdetails 及其服务。我在模型中实现了 userdetails,在服务中实现了服务。我将发布我在星期一完成的所有春季安全代码。到时候给你贴标签。感谢您的回复。
  • 正如周五晚上所讨论的,我已经添加了我是如何实现 Spring Security 的。我什至提到了krams915.blogspot.de/2012/01/… 来验证我是否正确。
  • 顺便说一句,我仍然遇到同样的问题。你能帮忙的话,我会很高兴。谢谢。
  • 所以我终于发现,personService 未初始化/为空,因为我在另一个控制器中使用它。我现在有投射错误,希望是 Spring Security 的最后一个问题,所以我可以回到 Spring。
  • 我检查了 if (a==null),它不是。我搜索了同一个问题,许多人似乎以不同的格式或方式遇到了同样的问题。
猜你喜欢
  • 2015-10-28
  • 2015-08-09
  • 2017-09-21
  • 2023-03-27
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 2014-01-12
相关资源
最近更新 更多