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.