Skip to content
Snippets Groups Projects
Forked from adi-ia / uw-spring-security
Source project has a limited visibility.
Nicholas Blair's avatar
Nicholas Blair authored
feature: a callback interface allowing customization of UserDetailsService#loadUserByUsername

This pull request adds a callback interface that allows downstream projects to participate in one of the core Spring Security components of the `local-users` profile: the UserDetailsService.

During an authentication attempt, `UserDetailsService#loadUserByUsername` is used by Spring Security to first check if a User object exists for the username in the credentials. If no User object is found, no further credential check takes place; if a User object is found, other Spring Security components go about comparing the provided credentials in the authentication attempt to that object.

We have a use case in DoIT Number that is driving the need for this. DoIT Number has a custom `UWUserDetails` class that has some additional fields stored behind a DAO. If we didn't have this customization, DoIT Number would need to sub-class `LocalUserDetailsManagerImpl`, then somehow exclude that bean from the UWSpringSecurityConfiguration - not trivially possible.

The existing `LocalUserDetailsAttributesMapper` interface has a lifecycle that's not conducive to this type of request. Implementations of that interface are executed during application startup - and it is possible that the DAO may not be fully constructed at the time it's queried. We need a callback that fires at time of authentication attempt - not startup.
 
With this pull request, DoIT Number will simply have to register a Spring Bean as follows to query that DAO and attach the necessary data to their custom `UWUserDetails` class as part of `UserDetailsService#loadUserByUsername`:

```
@Component
class DNumberLocalUWUserDetailsCallback implements LocalUWUserDetailsCallback<DNumberUserDetailsImpl> {

  @Autowired
  private ControlDao controlDao;

  public void success(DNumberUserDetailsImpl userDetails) {
    userDetails.setControls(controlDao.getControls(userDetails.getUsername()));
  }
}
```

This type of feature is only needed for `local-users` and not for `preauth`. The `PreauthenticatedUserDetailsAttributeMapper` interface has a lifecycle already similar to LocalUWUserDetailsCallback (firing on authentication attempt, not startup). 

Notify @alundholm 

See merge request !12
54b95e3c
History
Name Last commit Last update