Add method to get access token by providing refresh token in case of offline_access scope (2)

This commit is contained in:
Konstantinos Triantafyllou 2023-05-19 14:54:44 +03:00
parent e1a7bfc704
commit 78456aabd9
5 changed files with 115 additions and 3 deletions

View File

@ -1,10 +1,13 @@
package eu.dnetlib.authentication.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@ -39,4 +42,13 @@ public class AuthenticationConfiguration {
map.put("authentication.authorities-mapper", properties.getAuthoritiesMapper());
return map;
}
@Bean
RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper());
restTemplate.getMessageConverters().add(converter);
return restTemplate;
}
}

View File

@ -1,12 +1,15 @@
package eu.dnetlib.authentication.controllers;
import eu.dnetlib.authentication.entities.TokenResponse;
import eu.dnetlib.authentication.entities.User;
import eu.dnetlib.authentication.configuration.Properties;
import eu.dnetlib.authentication.services.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@ -31,6 +34,12 @@ public class UserController {
return ResponseEntity.ok(userInfoService.getUserInfo());
}
@RequestMapping(value = "/accessToken", method = RequestMethod.GET)
@PreAuthorize("@SecurityService.hasRefreshToken()")
public ResponseEntity<TokenResponse> getAccessToken(@RequestParam(name = "refreshToken") String refreshToken) {
return ResponseEntity.ok(this.userInfoService.getAccessToken(refreshToken));
}
@RequestMapping(value = "/redirect",method = RequestMethod.GET)
public void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();

View File

@ -1,2 +1,37 @@
package eu.dnetlib.authentication.entities;public class TokenResponse {
package eu.dnetlib.authentication.entities;
public class TokenResponse {
String access_token;
Long expires_in;
String id_token;
String refresh_token;
String scope;
String token_type;
public TokenResponse() {
}
public String getAccess_token() {
return access_token;
}
public Long getExpires_in() {
return expires_in;
}
public String getId_token() {
return id_token;
}
public String getRefresh_token() {
return refresh_token;
}
public String getScope() {
return scope;
}
public String getToken_type() {
return token_type;
}
}

View File

@ -1,2 +1,22 @@
package eu.dnetlib.authentication.services;public class SecurityService {
package eu.dnetlib.authentication.services;
import eu.dnetlib.authentication.utils.PropertyReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Set;
@Component(value = "SecurityService")
public class SecurityService {
Set<String> scopes;
@Autowired
public SecurityService(PropertyReader reader) {
this.scopes = reader.getScopes();
}
public boolean hasRefreshToken() {
return this.scopes.contains("offline_access");
}
}

View File

@ -1,20 +1,56 @@
package eu.dnetlib.authentication.services;
import eu.dnetlib.authentication.entities.TokenResponse;
import eu.dnetlib.authentication.entities.User;
import eu.dnetlib.authentication.exception.ResourceNotFoundException;
import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.config.ServerConfiguration;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Service
public class UserInfoService {
RestTemplate restTemplate;
RegisteredClient client;
ServerConfiguration server;
public UserInfoService(RestTemplate restTemplate, RegisteredClient client, ServerConfiguration server) {
this.restTemplate = restTemplate;
this.client = client;
this.server = server;
}
public User getUserInfo() throws ResourceNotFoundException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication instanceof OIDCAuthenticationToken) {
if (authentication instanceof OIDCAuthenticationToken) {
return new User((OIDCAuthenticationToken) authentication);
}
throw new ResourceNotFoundException("No Session has been found");
}
public TokenResponse getAccessToken(String refreshToken) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(getTokenRequest(refreshToken), headers);
return restTemplate.postForObject(this.server.getTokenEndpointUri(), entity, TokenResponse.class);
}
public MultiValueMap<String, String> getTokenRequest(String refreshToken) {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", this.client.getClientId());
map.add("client_secret", this.client.getClientSecret());
map.add("grant_type", "refresh_token");
map.add("refresh_token", refreshToken);
map.add("scope", "openid");
return map;
}
}