I'm experimenting with gRPC using a Spring based 'backend' and Android 'front-end', the idea is that I'll request an access token using the password grant type over HTTP (using the standard /oauth/token RESTful endpoint) and use the access token provided in all subsequent requests over RPC (setting the authorization header).
I have a gRPC server interceptor on my spring 'backend' that'll get the authorization header from the server call and authenticate the access token against the token store.
I'm stuck about what to do next or even if what I have so far is the 'correct' approach.
This is my interceptor:
@Component
public class GrpcRequestInterceptor implements ServerInterceptor {
private AuthenticationManager authenticationManager;
public GrpcRequestInterceptor(AuthenticationManager authenticationManager, AuthorizationCodeServices authorizationCodeServices) {
this.authenticationManager = authenticationManager;
}
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
String authorizationHeader = metadata.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
PreAuthenticatedAuthenticationToken preAuthenticatedAuthenticationToken =
new PreAuthenticatedAuthenticationToken(authorizationHeader.substring("Bearer ".length()), "");
PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthenticatedAuthenticationProvider();
preAuthenticatedAuthenticationProvider.setPreAuthenticatedUserDetailsService(new AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken>() {
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken preAuthenticatedAuthenticationToken) throws UsernameNotFoundException {
????
}
});
Authentication authentication = preAuthenticatedAuthenticationProvider.authenticate(preAuthenticatedAuthenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
return serverCallHandler.startCall(serverCall, metadata);
}
}
How do I get the token service and how do I authenticate my user against that service using just the access token I'm providing myself.
My security config is as follows:
@Configuration
@EnableAuthorizationServer
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AccountDetailsService accountDetailsService;
@Profile(value = "development")
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/h2-console/**");
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(accountDetailsService)
.passwordEncoder(initPasswordEncoder());
}
@Bean
public PasswordEncoder initPasswordEncoder() {
return new BCryptPasswordEncoder(10);
}
}
Should I be setting the token service manually in here and then injecting that into my interceptor or??? What's the 'springiest' way of getting this done?
Any help is greatly appreciated!