简体   繁体   中英

Spring boot: Permit specific services to avoid security

I have multiple services. All of them use jwt for authorization. However when my services communicate between each other I don't want them to authenticate. When Client sends a request to serviceA and serviceA needs data from serviceB it is enough for me that serviceA validates the token (also the other way around when the client sends a request to serviceB). I am using eureka as registry and openfeign to communicate between the services. Right now I always get a 401 response like this:

feign.FeignException$Unauthorized: [401] during [GET] to [http://userservice/eschuler]

To be more specific my authservice want to send a request to the userservice.

@FeignClient(name = "userservice")
public interface UserClient {
    @GetMapping(value = "/{id}")
    ResponseEntity<UserAccount> getUserById(@PathVariable String id);
}

This is the UserController containing the getUserById Method:

@RestController
@RequestMapping(value = "/kimoji/rest/users")
public class UserController {

    private final UserRepository userRepository;
    private final PasswordEncoder encoder;
    private final JwtTokenService jwtTokenService;

    public UserController(UserRepository userRepository, PasswordEncoder encoder, JwtTokenService jwtTokenService) {
        this.userRepository = userRepository;
        this.encoder = encoder;
        this.jwtTokenService = jwtTokenService;
    }

    @GetMapping(value = "/{id}")
    public ResponseEntity<UserAccount> getUserById(@PathVariable String id) {
        Optional<UserAccount> userAccount = userRepository.findById(id);
        return userAccount.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
    }


 ...
    
}

This is the WebSecurityConfig from my userservice:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) {
        authenticationManagerBuilder.authenticationProvider(jwtAuthenticationProvider);
    }

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() {
        return new JwtAuthenticationTokenFilter();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/kimoji/rest/users/register").permitAll()
                .anyRequest().authenticated();

        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
        httpSecurity.headers().cacheControl();
    }

}

Instead of avoiding security, what you want to do is always pass a token.

If the Service A is calling Service B and the request is originated from an external Client. Just pass the same token to Service B that originated from the Client to Service A.

If Service A is initiating the call (some sort of maintenance job) then use the Client Credentials flow to go to your Identity Provider and create a token for Service A to pass to Service B.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM