2

I would like to be able to change spring security slightly so that the name, email are accessible through the Principal object.

Also to log in I want to user the email and not username.

Where do I start or is this already possible?

1
  • after the version 5.8. there are in pre-5.8 and post-5.8 approaches. stackoverflow.com/questions/22643577 Commented Oct 6, 2024 at 14:23

1 Answer 1

1

Not impossible at all. You need to provide your own implementation of UserDetails though. Its not very difficult at all. This article shows one possible way to go about doing it. Below are some code that I used recently:

I started by providing my own UserDetails impelementation that suited my purposes. I actually have all the extra details in a Staff class and simply have a Many to One reference from MyUser to Staff. However, I simplified it for this answer and just included the fullName and email properties directly in the MyUser class.

public class MyUser implements UserDetails {

  @NotNull
  @Size(min = 3, max = 50)
  private String username;

  @NotNull
  @Size(min = 3, max = 256)
  private String password;

  private Boolean enabled;

  private Boolean accountNonLocked;

  private Boolean accountNonExpired;

  private Boolean credentialsNonExpired;

  private String email;

  private String fullName;

  private GrantedAuthority authorities;


  @Override      
  public Collection<GrantedAuthority> getAuthorities() {
    return authorities;
  }

  @Override
  public String toString() {
    return username;
  }

  @Override
public boolean isAccountNonExpired() {
      return this.accountNonExpired;
  }

  @Override
public boolean isCredentialsNonExpired() {
      return this.credentialsNonExpired;
  }

  @Override
public boolean isAccountNonLocked() {
      return this.accountNonLocked;
    }

  @Override
public boolean isEnabled() {
      return this.enabled;
    }

    public String getEmail(){
        return email;
    }

    public String getFullName(){
        return fullName;
    }
}

Then I provided my own User Details Service implementation because I use Hibernate to persist everything in a database. You may need a different implementation:

public class MyUserDetailsService implements UserDetailsService {

  @Override
  public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException {
      UserDetails userDetails = null;

    TypedQuery<MyUser> q = MyUser
            .findMyUsersByUsernameEquals(username);
    userDetails = q.getSingleResult();
    if (userDetails == null)
       throw new UsernameNotFoundException("user not found");
    return userDetails;
  } 

}

Then in the applicationContext-security.xml file I added this:

    <!-- Add a custom UserDetailsService -->
<beans:bean id="udservice" class="my.package.name.security.MyUserDetailsService"></beans:bean>

and this:

<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">      
    <authentication-provider user-service-ref="udservice">
        <password-encoder hash="sha-256" />     
    </authentication-provider>
</authentication-manager>

Now when you access the user that is logged in you get an instance of your class and access to all its properties.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.