Reputation: 330
I want to create two separate microservices. One as frontend with Vaadin Flow and another with Spring Boot REST API with security. The Spring API implements the JWT Security. I want the Vaadin app to call the REST API with user name and password and receive the JWT token as a response.
The Vaadin application authenticates the user for the dashboard. Every request wants to add a bearer token in the header and call the REST API.
Upvotes: 0
Views: 1013
Reputation: 1761
This is an simple example using Spring Web RestTemplate connecting to an URL with username and password in header and then receiving a Bearer token. You can use other libraries to achieve the same more or less.
// class should be session scoped or bearer put in users session
public class AuthenticateUser {
private final RestTemplate restTemplate = new RestTemplate();
private final String tokenUrl;
private String bearer;
public AuthenticateUser(String tokenUrl) {
// validate tokenUrl here
this.tokenUrl = tokenUrl;
}
public void authenticate(String username, String password) throws JsonProcessingException {
// validate username and password here
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("username", username);
body.add("password", password);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(body, headers);
final ResponseEntity<String> responseEntity = restTemplate.postForEntity(tokenUrl, entity, String.class);
if (responseEntity.hasBody()) {
ObjectMapper mapper = new ObjectMapper();
final JsonNode jsonNode = mapper.readTree(responseEntity.getBody());
// change access_token to whatever fits your JSON response
final JsonNode accessToken = jsonNode.get("access_token");
if (accessToken != null) {
bearer = accessToken.textValue();
}
if (bearer != null && !bearer.trim().equals("")) {
throw new IllegalStateException("No Bearer received");
}
}
}
}
When you have the bearer available you just add it to your header like this and do your POST/GET/DELETE etc.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer " + bearer); // proof of login
Dependencies in this example:
Important! Bearer TOKEN should be kept in users session and might be saved in uses session store for future reference until TOKEN timeout.
A token timeout can be handled by having a LocalDateTime field paired with the token. Update the field when you authenticate successfully and check the time when you access the bearer. If timed out reauthenticate and update bearer and time. Alternatively if timeout exception just reauthenticate.
I would consider having a separate authorization server handling authentication and authorization rather than having a backend server (running business) being responsible also for authentication and authorization. There is Keycloak, Auth0, Okta, Spring Authorization Server (0.2.0 atm), and more alternatives for you to choose from. Some only as online providers other as self hosted option.
Upvotes: 1