diff --git a/src/main/java/eu/dnetlib/authentication/configuration/AuthenticationConfiguration.java b/src/main/java/eu/dnetlib/authentication/configuration/AuthenticationConfiguration.java index af0d3ce..8241d10 100644 --- a/src/main/java/eu/dnetlib/authentication/configuration/AuthenticationConfiguration.java +++ b/src/main/java/eu/dnetlib/authentication/configuration/AuthenticationConfiguration.java @@ -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; + } } diff --git a/src/main/java/eu/dnetlib/authentication/controllers/UserController.java b/src/main/java/eu/dnetlib/authentication/controllers/UserController.java index 1f5f128..6b9bc2f 100644 --- a/src/main/java/eu/dnetlib/authentication/controllers/UserController.java +++ b/src/main/java/eu/dnetlib/authentication/controllers/UserController.java @@ -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 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(); diff --git a/src/main/java/eu/dnetlib/authentication/entities/TokenResponse.java b/src/main/java/eu/dnetlib/authentication/entities/TokenResponse.java index 948d60b..c1220f6 100644 --- a/src/main/java/eu/dnetlib/authentication/entities/TokenResponse.java +++ b/src/main/java/eu/dnetlib/authentication/entities/TokenResponse.java @@ -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; + } } diff --git a/src/main/java/eu/dnetlib/authentication/services/SecurityService.java b/src/main/java/eu/dnetlib/authentication/services/SecurityService.java index ab9effb..660c099 100644 --- a/src/main/java/eu/dnetlib/authentication/services/SecurityService.java +++ b/src/main/java/eu/dnetlib/authentication/services/SecurityService.java @@ -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 scopes; + + @Autowired + public SecurityService(PropertyReader reader) { + this.scopes = reader.getScopes(); + } + + public boolean hasRefreshToken() { + return this.scopes.contains("offline_access"); + } } diff --git a/src/main/java/eu/dnetlib/authentication/services/UserInfoService.java b/src/main/java/eu/dnetlib/authentication/services/UserInfoService.java index b6a3708..a9085c4 100644 --- a/src/main/java/eu/dnetlib/authentication/services/UserInfoService.java +++ b/src/main/java/eu/dnetlib/authentication/services/UserInfoService.java @@ -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> entity = new HttpEntity<>(getTokenRequest(refreshToken), headers); + return restTemplate.postForObject(this.server.getTokenEndpointUri(), entity, TokenResponse.class); + } + + public MultiValueMap getTokenRequest(String refreshToken) { + MultiValueMap 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; + } }