Issue
I have an application made with Spring that uses JWT authentication.
I would like to know if you have the possibility to release a route depending on which client is accessing my back end, for example:
clientA:8080
- has/health
route allowed without authenticationclientB:8081
- has/health
route not allowed without JWT authentication.
I had tried something like this:
http.authorizeRequests().antMatchers("http://clientA/health").permitAll()
but it didn't work.
Solution
I strongly advise against this kind of authentication that is not a strong authentication mechanism. However you can achieve like you would do for multiple auth. Basically you need multiple WebSecurityConfigurerAdapter with a requestMatcher.
Here is a quick sample (DON'T DO IT):
Security configurations
@Configuration
@EnableWebSecurity
public class SecurityConfigurations {
@Configuration
@Order(1)
public static class NoAuth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.requestMatcher(r -> r.getRequestURL().toString().startsWith("http://localhost:8081"))
.authorizeRequests()
.anyRequest().permitAll();
}
}
@Configuration
@Order(2)
public static class Auth extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
final byte[] salt = "random".getBytes(StandardCharsets.UTF_8);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
System.out.println(Base64.getEncoder().encodeToString(key.getEncoded()));
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.decoder(NimbusJwtDecoder.withSecretKey(key).build());
}
}
}
Application configuration:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ServletWebServerFactory serverContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createConnector());
return tomcat;
}
private Connector createConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(8081);
connector.setScheme("http");
connector.setSecure(false);
return connector;
}
}
Controller
@RestController
public class HealthApi {
@GetMapping("/health")
public String health() {
return "healthy";
}
}
You can test it with curl:
curl -v localhost:8081/health
200 OK healthy
curl -v localhost:8080/health
401
curl -v -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.LUn3qZESwtUIbXrD3WSd3CNEOTwbKV9x2IahoLUCyAs" localhost:8080/health
200 OK healthy
Answered By - JEY
Answer Checked By - Katrina (JavaFixing Volunteer)