Spring Security无法检索当前经过身份验证的用户

时间:2014-10-24 13:05:17

标签: spring-mvc spring-security

我正在开发一个使用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;
    }
}

LoginServiceImpl:

@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);
    }
}

汇编程序类:

@服务(&#34;汇编&#34)

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>

1 个答案:

答案 0 :(得分:1)

这仍然不是一个真正的答案,但是太长,无法适应评论。

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

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

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

一旦有效,您将添加更多功能。如果没有,很难找到问题的原因。

编辑:

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

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

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