-
Notifications
You must be signed in to change notification settings - Fork 60
Closed
Milestone
Description
My application is Native gRPC Server inside a Servlet Container. Security code in my project
Config
@Bean
@GlobalServerInterceptor
AuthenticationProcessInterceptor jwtSecurityFilterChain(GrpcSecurity grpc) throws Exception {
return grpc.authorizeRequests(requests -> requests.allRequests().permitAll())
.authenticationManager(authenticationManager)
.authenticationExtractor(new BearerTokenAuthenticationExtractor())
.httpBasic(withDefaults())
.preauth(withDefaults())
.build();
}Annotations
@Override
@PreAuthorize("hasAuthority('OperationAdmin')")
public void createRegion(
CreateRegionRequest request, StreamObserver<DescribeRegionResponse> responseObserver) {
//TODO
}When some one is logged in our system, another one can access the gRPC method without logging. I do some research for this strange behavior. Here is the default security interceptor: AuthenticationProcessInterceptor, I can not find out any code to clear SecurityContext when call is completed.
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication user = this.extractor.extract(headers, call.getAttributes());
if (user != null) {
user = this.authenticationManager.authenticate(user);
securityContext.setAuthentication(user);
}
if (this.authorizationManager != null) {
CallContext context = new CallContext(headers, call.getAttributes(), call.getMethodDescriptor());
if (user == null) {
// Maybe just throw BadCredentialsException (authentication manager would
// have to make the anonymous user)?
user = new AnonymousAuthenticationToken("anonymous", "anonymous",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
}
Authentication authentication = user;
if (!this.authorizationManager.authorize(() -> authentication, context).isGranted()) {
if (user instanceof AnonymousAuthenticationToken) {
throw new BadCredentialsException("not authenticated");
}
throw new AccessDeniedException("not allowed");
}
}
else if (user == null || !user.isAuthenticated()) {
throw new BadCredentialsException("not authenticated");
}
return next.startCall(call, headers);
}And the SecurityContextServerInterceptor is not registered by default. So the SecurityContext is not clear by default, and anonymous can reuse SecurityContext to access the protected gRPC method. Is this a bug or I missed some configuration? In common sense, SecurityContext will be cleared after request is completed or interrupted by default
@ConditionalOnBean(SecurityFilterChain.class)
@Conditional(GrpcServerFactoryAutoConfiguration.OnGrpcServletCondition.class)
@Configuration(proxyBeanMethods = false)
class GrpcServletSecurityConfigurerAutoConfiguration {
@Bean
@GlobalServerInterceptor
public SecurityContextServerInterceptor securityContextInterceptor() {
return new SecurityContextServerInterceptor();
}
@Bean
public <T extends ServerBuilder<T>> ServerBuilderCustomizer<T> securityContextExecutorCustomizer() {
return (serverBuilder) -> serverBuilder
.executor(new DelegatingSecurityContextExecutor(GrpcUtil.SHARED_CHANNEL_EXECUTOR.create()));
}
}hellozdp, HyunSangHan and JustinSongXh
Metadata
Metadata
Assignees
Labels
No labels