We are Borg
We are Borg

Reputation: 5313

Spring Security cannot retreieve Currently authenticated user

I am working on a Spring-MVC application which uses Spring-Security. In that I need to get the currently authenticated user's object so I can use setUser() method. However the method returns null, the program seems to crash with a null pointer exception. Kindly have a look at the code. I already debugged+try-catch it and it doesn't return the user.

The call getCurrentlyAuthenticatedUser() throws exception. When I check, it says authentication is null.

I have implemented Spring-Security by implementing the interface UserDetails and UserDetailsService.

Person Class :

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

Assembler class :

@Service("assembler")

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

// I get error in below method at 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>

Upvotes: 0

Views: 694

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 149155

It is not still a real answer, but too long to fit in a comment.

You never test if objects returned from other methods are not null before using them. I think that the most probable error is that SecurityContextHolder.getContext().getAuthentication(); returns null causing the NPE on next line. If that's true, that mean that your problem is in the configuration of Spring security. But it is not possible to say more without seeing the bean userDetailsService. You say you implemented userDetail and UserDetailsService but do not show how.

I advice your to remove remember_me as long as you do not have a working basic configuration, that is one where :

  • you have to login before accessing protected pages
  • you can find the logged user in SecurityContextHolder.getContext().getAuthentication()

You will add more functionnalities once this works. If not, it will be very hard to find the causes of your problems.

Edit:

You say the error occurs on line Person currentUser = (Person) a.getPrincipal();. It is now clear that in previous line

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

getAuthentication() returned null. It means that for Spring security, there is no currently authenticated user.

Upvotes: 1

Related Questions