Skip to content

SEC-2983: InMemoryUserDetailsManager#loadUserByUsername should preserve custom UserDetails types #3192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue May 23, 2015 · 1 comment
Assignees
Labels
in: core An issue in spring-security-core type: enhancement A general enhancement type: jira An issue that was migrated from JIRA

Comments

@spring-projects-issues
Copy link

William Gorder (Migrated from SEC-2983) said:

Is there a good reason for not returning MutableUser.delegate in the InMemoryUserDetailsManager.loadUserByUsername() method? What I have run into is I want to provide my own user details, so I pass them to the create() method but when I get them back from authentication.getPrincipal() its been replaced with the vanilla spring security User object since apparently rather then just returning the UserDetails that we already have it takes the delegate and creates a new org.springframework.security.core.userdetails.User.

What I am proposing is a something different then the MutableUserDetails interface. The MutableUser object would need to expose its delegate so that it could be returned if it exists. Currently the only way to get what I want is to create my own version of InMemoryUserDetailsManager and InMemoryUserDetailsManagerConfigurer unless I am missing something. It just seems that by exposing a create(UserDetails) method it is implied that we would get the UserDetails provided and not something different. I see this bit of the API as confusing and bit misleading. There is nothing in the Java Doc implying that that underlying implementation will be changed.

@spring-projects-issues spring-projects-issues added in: core An issue in spring-security-core Open type: bug A general bug type: jira An issue that was migrated from JIRA labels Feb 5, 2016
@rwinch rwinch removed the Open label May 3, 2019
@jzheaux jzheaux self-assigned this Jun 4, 2024
@jzheaux
Copy link
Contributor

jzheaux commented Jun 4, 2024

Is there a good reason for not returning MutableUser.delegate in the InMemoryUserDetailsManager.loadUserByUsername() method?

I believe one benefit is that User implements CredentialsContainer, ensuring that the password will be removed completely after authentication.

Currently the only way to get what I want is to create my own version of InMemoryUserDetailsManager and InMemoryUserDetailsManagerConfigurer

Things have obviously changed a lot since the 3.x days. Today publishing a UserDetailsManager bean or, even simpler, a UserDetailsService is quite simple and is the recommended route for custom UserDetails implementations.

That said, one thing I think we could do is store any MutableUserDetails instead of wrapping it like so:

public void createUser(UserDetails user) {
    if (user instanceof MutableUserDetails mutable) {
        this.users.put(user.getUsername().toLowerCase(), mutable);
    } else {
        this.users.put(user.getUsername().toLowerCase(), new MutableUser(user));
    }
}

// ...

public UserDetails loadUserByUsername(String username) ...
    UserDetails user = this.users.get(username.toLowerCase());
    if (user == null ) ...
    if (user instanceof CredentialsContainer container) {
        return container;
    }
    return new User(...);
}

In this way, I believe the credential-clearing functionality would be preserved, MutableUser would remain untouched, and you would have easy access to your custom type through casting.

@jzheaux jzheaux added type: enhancement A general enhancement status: ideal-for-contribution An issue that we actively are looking for someone to help us with and removed type: bug A general bug labels Jun 4, 2024
@jzheaux jzheaux changed the title SEC-2983: Why not return the delegate in InMemoryUserDetailsManager.loadUserByUsername() SEC-2983: InMemoryUserDetailsManager#loadUserByUsername should preserve custom UserDetails types Jun 5, 2024
MrJovanovic13 added a commit to MrJovanovic13/spring-security that referenced this issue Jul 29, 2024
@jzheaux jzheaux removed the status: ideal-for-contribution An issue that we actively are looking for someone to help us with label Jul 29, 2024
MrJovanovic13 added a commit to MrJovanovic13/spring-security that referenced this issue Jul 31, 2024
MrJovanovic13 added a commit to MrJovanovic13/spring-security that referenced this issue Jul 31, 2024
Tests added:
createUserWhenUserAlreadyExistsThenException
updateUserWhenUserDoesNotExistThenException
loadUserByUsernameWhenUserNullThenException

Issue spring-projectsgh-3192
MrJovanovic13 added a commit to MrJovanovic13/spring-security that referenced this issue Jul 31, 2024
jzheaux pushed a commit that referenced this issue Aug 9, 2024
Tests added:
createUserWhenUserAlreadyExistsThenException
updateUserWhenUserDoesNotExistThenException
loadUserByUsernameWhenUserNullThenException

Issue gh-3192
@jzheaux jzheaux closed this as completed in 6d657ea Aug 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core An issue in spring-security-core type: enhancement A general enhancement type: jira An issue that was migrated from JIRA
Projects
None yet
Development

No branches or pull requests

3 participants