I have a problem with Spring Security OAuth2. There is a kiosk system where all the kiosks need to authorize with a central OAuth2 provider during launch. There are two stores for credentials -- one for actual users (e.g technicians) and another one for kiosks. The collection for kiosks store kiosk profile information, which is essentially serial numbers of all the devices used in a kiosk (bill acceptor, cash dispenser, thermal printer etc).
So, here is the flow that I am trying to achieve.
grant_type=kiosk
Now, I have created a new grant type for kiosk authorization. But I need a way to access my Kiosk Profile Data Mapper, which is a Spring service. So, in my class I add the following:
class KioskTokenGranter extends AbstractTokenGranter {
@Autowire
KioskProfileService kioskProfile;
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
// request parsing stuff
kioskProfile.findByAttributes(...);
}
}
The snipper above gives me a NullPointerException that kioskProfile
does not exist. If I do the same thing in AuthorizationServerConfigurerAdapter, autowire works. So, my question is how to Autowire a service inside TokenGranter.
It appears you're just running into the plain old problem where the objects you are instantiating aren't controlled by Spring. You haven't annotated your class as a @Component
or anything like that (not that I would recommend you do in this case). Spring isn't aware of your @Autowire annotation.
For another example of someone's implementation of AbstractTokenGranter, take OBOTokenGranter.java.
public class OBOTokenGranter extends AbstractTokenGranter {
...
private UserDetailsService uds;
public OBOTokenGranter(UserDetailsService uds, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
OAuth2RequestFactory requestFactory) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.uds = uds;
}
...
}
Note that UserDetailsService uds
is being passed in via the constructor instead of autowired in. You can see the usaged of OBOTokenGranter
in OBOTokenGenerator.java, which is a @RestController
and has the UserDetailService
autowired into it, so that it can be used in construction of the Granter.
@RestController
public class OBOTokenGenerator {
...
@Autowired
private UserDetailsService uds;
...
@RequestMapping("/obo/{user}")
public ResponseEntity<OAuth2AccessToken> getOBOToken(Principal principal, @PathVariable("user") String user) {
...
OBOTokenGranter granter = new OBOTokenGranter(uds, tokenServices, clientDetailsService, requestFactory);
...
}
So the question remaining is: does your code follow this pattern of usage? Do you have a Controller/Service/Component/etc that constructs the KioskTokenGranter
?