Description
Describe the bug
Problem is a possible NullPointerException
(NPE) in DefaultOAuth2User.getName
.
To Reproduce
Get null value on the name attribute during after OAuth authentaction.
Or simply create attributes for DefaultOAuth2User
as show in the Sample.
Expected behavior
NPE shouldn't be going around Spring Security. It should maybe use throw new UsernameNotFoundException(.)
, not sure.
Sample
This is a minimal example to reproduce (without setting up an oauth2 server):
Collection<GrantedAuthority> authorities = Arrays.asList(
new SimpleGrantedAuthority("ROLE_USER")
);
var attributes = new HashMap<String, Object>();
var nameAttributeKey = "Email";
attributes.put("UserName", "");
// notice this is in the attributes, but is null
attributes.put(nameAttributeKey, null);
var test = new DefaultOAuth2User(authorities, attributes, nameAttributeKey);
test.getName();
This code is a problem:
@Override
public String getName() {
return this.getAttribute(this.nameAttributeKey).toString();
}
Real code
In a real use case this was the attributes of the DefaultOAuth2User:
User Attributes: [{UserName=, Email=null, Authenticated=false, Claims=null}]
The name field was "Email", but I guess it could be anything that just so happens to be null. Note that attributes are from an external service. The service is defined by userInfoUri
from FactoryBean<T>
. So the attributes are essentially attributes of a user profile as returned by the identity provider (idP).
This is how getName was originally called:
public class OAuth2UserServiceImpl extends DefaultOAuth2UserService {
private static final Logger LOG = LoggerFactory.getLogger(OAuth2UserServiceImpl.class);
// ...
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oauth2user = super.loadUser(userRequest);
final String providerId = userRequest.getClientRegistration().getRegistrationId();
// this results in NPE
final String username = oauth2user.getName();
// ...
}