Compare commits

..

22 Commits

Author SHA1 Message Date
Konstantinos Triantafyllou a191ca62a6 [maven-release-plugin] prepare for next development iteration 2023-12-14 15:21:09 +02:00
Konstantinos Triantafyllou 2c523edebc [maven-release-plugin] prepare release uoa-login-core-2.1.1 2023-12-14 15:21:05 +02:00
Konstantinos Triantafyllou 8abd6b7307 Move WebMvcConfigurer under AuthenticiationConfiguration. 2023-12-14 15:20:48 +02:00
Konstantinos Triantafyllou 048e51269a [maven-release-plugin] prepare for next development iteration 2023-11-24 12:11:57 +02:00
Konstantinos Triantafyllou d25fb2fc53 [maven-release-plugin] prepare release uoa-login-core-2.1.0 2023-11-24 12:11:54 +02:00
Konstantinos Triantafyllou aecbab92a5 Add default empty authorities mapper and initialize openaire authorities mapper only if property has value eduperson_entitlement. 2023-11-24 12:11:26 +02:00
Konstantinos Triantafyllou 43f0d8f3da Add orcid in User 2023-09-07 11:17:35 +03:00
Konstantinos Triantafyllou cf6e4afcf0 [maven-release-plugin] prepare for next development iteration 2023-07-27 14:04:40 +03:00
Konstantinos Triantafyllou 8036b261cf [maven-release-plugin] prepare release uoa-login-core-2.0.3 2023-07-27 14:04:36 +03:00
Konstantinos Triantafyllou 57e6aa7ccd Change HealthController to LoginCoreDeployController 2023-07-27 14:04:12 +03:00
Konstantinos Triantafyllou eb3e6c82e7 Add Health Controller and global vars 2023-07-27 12:59:33 +03:00
Konstantinos Triantafyllou c3c6d66d29 Add revoke with refresh token method and remove deleteOldTokens 2023-07-26 18:23:20 +03:00
Konstantinos Triantafyllou 2d2796053d [maven-release-plugin] prepare for next development iteration 2023-07-06 15:06:39 +03:00
Konstantinos Triantafyllou a81dcd7ae1 [maven-release-plugin] prepare release uoa-login-core-2.0.2 2023-07-06 15:06:35 +03:00
Konstantinos Triantafyllou 0b93b16059 Add filter to convert getRequestURL in AuthenticationFilter. 2023-07-06 15:06:18 +03:00
Konstantinos Triantafyllou 4fee4ddd8d [maven-release-plugin] prepare for next development iteration 2023-06-30 12:15:16 +03:00
Konstantinos Triantafyllou 08bff19dd9 [maven-release-plugin] prepare release uoa-login-core-2.0.1 2023-06-30 12:15:13 +03:00
Konstantinos Triantafyllou a73b74b879 Fix path for logout for oidc 2023-06-30 12:14:21 +03:00
Konstantinos Triantafyllou e5e95fce31 Fix paths base on issuer url and mode. Add getAccessToken and delete old refresh tokens (works only for oidc) 2023-06-26 11:35:38 +03:00
Konstantinos Triantafyllou 78456aabd9 Add method to get access token by providing refresh token in case of offline_access scope (2) 2023-05-19 14:54:44 +03:00
Konstantinos Triantafyllou e1a7bfc704 Add method to get access token by providing refresh token in case of offline_access scope 2023-05-19 14:54:23 +03:00
Konstantinos Triantafyllou 7fddb4f1e6 [maven-release-plugin] prepare for next development iteration 2023-05-18 12:43:25 +03:00
17 changed files with 345 additions and 72 deletions

View File

@ -7,17 +7,17 @@
<version>1.0.0</version> <version>1.0.0</version>
</parent> </parent>
<artifactId>uoa-login-core</artifactId> <artifactId>uoa-login-core</artifactId>
<version>2.0.0</version> <version>2.1.2-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>uoa-login-core</name> <name>uoa-login-core</name>
<scm> <scm>
<developerConnection>scm:git:gitea@code-repo.d4science.org:MaDgIK/uoa-login-core.git</developerConnection> <developerConnection>scm:git:gitea@code-repo.d4science.org:MaDgIK/uoa-login-core.git</developerConnection>
<tag>uoa-login-core-2.0.0</tag> <tag>HEAD</tag>
</scm> </scm>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<timestampLogincORE>${maven.build.timestamp}</timestampLogincORE> <timestampLoginCore>${maven.build.timestamp}</timestampLoginCore>
<maven.build.timestamp.format>E MMM dd HH:mm:ss z yyyy</maven.build.timestamp.format> <maven.build.timestamp.format>E MMM dd HH:mm:ss z yyyy</maven.build.timestamp.format>
</properties> </properties>
<dependencies> <dependencies>

View File

@ -1,38 +0,0 @@
package eu.dnetlib.authentication.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("api")
public class APIProperties {
private String title;
private String description;
private String version;
public APIProperties() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}

View File

@ -1,24 +1,32 @@
package eu.dnetlib.authentication.configuration; package eu.dnetlib.authentication.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@Configuration @Configuration
@EnableConfigurationProperties({Properties.class, APIProperties.class}) @EnableConfigurationProperties({Properties.class, GlobalVars.class})
@ComponentScan(basePackages = {"eu.dnetlib.authentication"}) @ComponentScan(basePackages = {"eu.dnetlib.authentication"})
public class AuthenticationConfiguration { public class AuthenticationConfiguration {
private final Properties properties; private final Properties properties;
private final GlobalVars globalVars;
@Autowired @Autowired
public AuthenticationConfiguration(Properties properties) { public AuthenticationConfiguration(Properties properties, GlobalVars globalVars) {
this.properties = properties; this.properties = properties;
this.globalVars = globalVars;
} }
public Map<String, String> getProperties() { public Map<String, String> getProperties() {
@ -37,6 +45,36 @@ public class AuthenticationConfiguration {
map.put("authentication.accessToken", properties.getAccessToken()); map.put("authentication.accessToken", properties.getAccessToken());
map.put("authentication.redirect", properties.getRedirect()); map.put("authentication.redirect", properties.getRedirect());
map.put("authentication.authorities-mapper", properties.getAuthoritiesMapper()); map.put("authentication.authorities-mapper", properties.getAuthoritiesMapper());
if(GlobalVars.date != null) {
map.put("Date of deploy", GlobalVars.date.toString());
}
if(globalVars.getBuildDate() != null) {
map.put("Date of build", globalVars.getBuildDate());
}
if (globalVars.getVersion() != null) {
map.put("Version", globalVars.getVersion());
}
return map; return map;
} }
@Bean
RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper());
restTemplate.getMessageConverters().add(converter);
return restTemplate;
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowCredentials(true);
}
};
}
} }

View File

@ -0,0 +1,31 @@
package eu.dnetlib.authentication.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Date;
@ConfigurationProperties("authentication.global-vars")
public class GlobalVars {
public static Date date = new Date();
private Date buildDate;
private String version;
public String getBuildDate() {
if(buildDate == null) {
return null;
}
return buildDate.toString();
}
public void setBuildDate(Date buildDate) {
this.buildDate = buildDate;
}
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
}

View File

@ -0,0 +1,39 @@
package eu.dnetlib.authentication.controllers;
import eu.dnetlib.authentication.configuration.AuthenticationConfiguration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/login-core")
public class LoginCoreCheckDeployController {
private final Logger log = LogManager.getLogger(this.getClass());
private final AuthenticationConfiguration configuration;
@Autowired
public LoginCoreCheckDeployController(AuthenticationConfiguration configuration) {
this.configuration = configuration;
}
@RequestMapping(value = {"", "/health_check"}, method = RequestMethod.GET)
public String hello() {
log.debug("Hello from Login Core");
return "Hello from Login Core!";
}
@PreAuthorize("hasAnyAuthority('PORTAL_ADMINISTRATOR')")
@RequestMapping(value = "/health_check/advanced", method = RequestMethod.GET)
public Map<String, String> checkEverything() {
Map<String, String> response = configuration.getProperties();
return response;
}
}

View File

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

View File

@ -0,0 +1,37 @@
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

@ -13,7 +13,10 @@ public class User {
private String given_name; private String given_name;
private String family_name; private String family_name;
private String email; private String email;
private String orcid;
private Set<String> roles; private Set<String> roles;
private String accessToken;
private String refreshToken;
public User(OIDCAuthenticationToken token) { public User(OIDCAuthenticationToken token) {
this.sub = token.getUserInfo().getSub(); this.sub = token.getUserInfo().getSub();
@ -21,7 +24,12 @@ public class User {
this.given_name = token.getUserInfo().getGivenName(); this.given_name = token.getUserInfo().getGivenName();
this.family_name = token.getUserInfo().getFamilyName(); this.family_name = token.getUserInfo().getFamilyName();
this.email = token.getUserInfo().getEmail(); this.email = token.getUserInfo().getEmail();
if(token.getUserInfo().getSource().get("orcid") != null) {
this.orcid = token.getUserInfo().getSource().get("orcid").getAsString();
}
this.roles = token.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); this.roles = token.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
this.accessToken = token.getAccessTokenValue();
this.refreshToken = token.getRefreshTokenValue();
} }
public String getSub() { public String getSub() {
@ -64,6 +72,14 @@ public class User {
this.email = email; this.email = email;
} }
public String getOrcid() {
return orcid;
}
public void setOrcid(String orcid) {
this.orcid = orcid;
}
public Set<String> getRoles() { public Set<String> getRoles() {
return roles; return roles;
} }
@ -71,4 +87,20 @@ public class User {
public void setRoles(Set<String> roles) { public void setRoles(Set<String> roles) {
this.roles = roles; this.roles = roles;
} }
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
} }

View File

@ -1,16 +0,0 @@
package eu.dnetlib.authentication.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowCredentials(true);
}
}

View File

@ -1,12 +1,13 @@
package eu.dnetlib.authentication.security.initiliazers; package eu.dnetlib.authentication.security.initiliazers;
import eu.dnetlib.authentication.configuration.Properties; import eu.dnetlib.authentication.configuration.Properties;
import eu.dnetlib.authentication.security.oidc.OpenAIREAuthoritiesMapper; import eu.dnetlib.authentication.security.oidc.DefaultAuthoritiesMapper;
import eu.dnetlib.authentication.security.oidc.OpenAIREUserInfoFetcher; import eu.dnetlib.authentication.security.oidc.OpenAIREUserInfoFetcher;
import eu.dnetlib.authentication.utils.PropertyReader; import eu.dnetlib.authentication.utils.PropertyReader;
import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.RegisteredClient; import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.client.OIDCAuthenticationProvider; import org.mitre.openid.connect.client.OIDCAuthenticationProvider;
import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
import org.mitre.openid.connect.config.ServerConfiguration; import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -14,19 +15,20 @@ import org.springframework.context.annotation.Configuration;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional;
@Configuration @Configuration
public class Configurations { public class Configurations {
private final Properties properties; private final Properties properties;
private final PropertyReader scopeReader; private final PropertyReader scopeReader;
private final OpenAIREAuthoritiesMapper authoritiesMapper;
private final OpenAIREUserInfoFetcher userInfoFetcher; private final OpenAIREUserInfoFetcher userInfoFetcher;
private final OIDCAuthoritiesMapper authoritiesMapper;
@Autowired @Autowired
public Configurations(Properties properties, OpenAIREAuthoritiesMapper authoritiesMapper, OpenAIREUserInfoFetcher userInfoFetcher, PropertyReader scopeReader) { public Configurations(Properties properties, Optional<OIDCAuthoritiesMapper> authoritiesMapper, OpenAIREUserInfoFetcher userInfoFetcher, PropertyReader scopeReader) {
this.properties = properties; this.properties = properties;
this.authoritiesMapper = authoritiesMapper; this.authoritiesMapper = authoritiesMapper.orElse(new DefaultAuthoritiesMapper());
this.userInfoFetcher = userInfoFetcher; this.userInfoFetcher = userInfoFetcher;
this.scopeReader = scopeReader; this.scopeReader = scopeReader;
} }
@ -37,7 +39,7 @@ public class Configurations {
if(properties.getKeycloak()) { if(properties.getKeycloak()) {
provider.setUserInfoFetcher(this.userInfoFetcher); provider.setUserInfoFetcher(this.userInfoFetcher);
} }
if(this.properties.getAuthoritiesMapper() != null && this.scopeReader.getScopes().contains(this.properties.getAuthoritiesMapper())) { if(this.authoritiesMapper != null) {
provider.setAuthoritiesMapper(this.authoritiesMapper); provider.setAuthoritiesMapper(this.authoritiesMapper);
} }
return provider; return provider;
@ -54,13 +56,14 @@ public class Configurations {
serverConfiguration.setTokenEndpointUri(issuer + "/protocol/openid-connect/token"); serverConfiguration.setTokenEndpointUri(issuer + "/protocol/openid-connect/token");
serverConfiguration.setUserInfoUri(issuer + "/protocol/openid-connect/userinfo"); serverConfiguration.setUserInfoUri(issuer + "/protocol/openid-connect/userinfo");
serverConfiguration.setJwksUri(issuer + "/protocol/openid-connect/certs"); serverConfiguration.setJwksUri(issuer + "/protocol/openid-connect/certs");
serverConfiguration.setRevocationEndpointUri(issuer + "/protocol/openid-connect/revoke");
} else { } else {
serverConfiguration.setAuthorizationEndpointUri(issuer + "/authorize"); serverConfiguration.setAuthorizationEndpointUri(issuer + "authorize");
serverConfiguration.setTokenEndpointUri(issuer + "/token"); serverConfiguration.setTokenEndpointUri(issuer + "token");
serverConfiguration.setUserInfoUri(issuer + "/userinfo"); serverConfiguration.setUserInfoUri(issuer + "userinfo");
serverConfiguration.setJwksUri(issuer + "/jwk"); serverConfiguration.setJwksUri(issuer + "jwk");
serverConfiguration.setRevocationEndpointUri(issuer + "revoke");
} }
serverConfiguration.setRevocationEndpointUri(issuer + "/revoke");
return serverConfiguration; return serverConfiguration;
} }

View File

@ -0,0 +1,17 @@
package eu.dnetlib.authentication.security.oidc;
import com.nimbusds.jwt.JWT;
import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
import org.mitre.openid.connect.model.UserInfo;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
import java.util.HashSet;
public class DefaultAuthoritiesMapper implements OIDCAuthoritiesMapper {
@Override
public Collection<? extends GrantedAuthority> mapAuthorities(JWT jwtToken, UserInfo userInfo) {
return new HashSet<>();
}
}

View File

@ -6,7 +6,12 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.mitre.openid.connect.client.OIDCAuthenticationFilter; import org.mitre.openid.connect.client.OIDCAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@ -20,6 +25,24 @@ public class OpenAIREAuthenticationFilter extends OIDCAuthenticationFilter {
this.properties = properties; this.properties = properties;
} }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletRequestWrapper wrapped = new HttpServletRequestWrapper((HttpServletRequest) req) {
@Override
public StringBuffer getRequestURL() {
final StringBuffer originalUrl = ((HttpServletRequest) getRequest()).getRequestURL();
if(originalUrl.toString().contains(OIDCAuthenticationFilter.FILTER_PROCESSES_URL)) {
return new StringBuffer(properties.getOidc().getHome());
} else if(properties.getOidc().getRedirect() != null){
return new StringBuffer(properties.getOidc().getRedirect());
} else {
return originalUrl;
}
}
};
super.doFilter(wrapped, res, chain);
}
@Override @Override
protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
Redirect.setRedirect(request, properties); Redirect.setRedirect(request, properties);

View File

@ -7,12 +7,16 @@ import eu.dnetlib.authentication.utils.AuthoritiesMapper;
import org.mitre.openid.connect.client.OIDCAuthoritiesMapper; import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
import org.mitre.openid.connect.model.UserInfo; import org.mitre.openid.connect.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collection; import java.util.Collection;
@Component @Component
@ConditionalOnProperty(
value="authentication.authorities-mapper",
havingValue = "eduperson_entitlement")
public class OpenAIREAuthoritiesMapper implements OIDCAuthoritiesMapper { public class OpenAIREAuthoritiesMapper implements OIDCAuthoritiesMapper {
private final Properties properties; private final Properties properties;

View File

@ -46,7 +46,7 @@ public class OpenAIRELogoutSuccessHandler implements LogoutSuccessHandler {
sb.append("?client_id=").append(properties.getOidc().getId()); sb.append("?client_id=").append(properties.getOidc().getId());
sb.append("&post_logout_redirect_uri=").append(encodeValue(properties.getOidc().getRedirect())); sb.append("&post_logout_redirect_uri=").append(encodeValue(properties.getOidc().getRedirect()));
} else { } else {
sb.append("/saml/logout"); sb.append("saml/logout");
} }
response.sendRedirect(sb.toString()); response.sendRedirect(sb.toString());
} }

View File

@ -0,0 +1,22 @@
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,83 @@
package eu.dnetlib.authentication.services; package eu.dnetlib.authentication.services;
import eu.dnetlib.authentication.configuration.Properties;
import eu.dnetlib.authentication.entities.TokenResponse;
import eu.dnetlib.authentication.entities.User; import eu.dnetlib.authentication.entities.User;
import eu.dnetlib.authentication.exception.ResourceNotFoundException; import eu.dnetlib.authentication.exception.ResourceNotFoundException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.config.ServerConfiguration;
import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Service @Service
public class UserInfoService { public class UserInfoService {
private static final Logger logger = LogManager.getLogger(UserInfoService.class);
RestTemplate restTemplate;
String issuer;
RegisteredClient client;
ServerConfiguration server;
@Autowired
public UserInfoService(RestTemplate restTemplate, Properties properties, RegisteredClient client, ServerConfiguration server) {
this.restTemplate = restTemplate;
this.issuer = properties.getOidc().getIssuer();
this.server = server;
this.client = client;
}
public User getUserInfo() throws ResourceNotFoundException { public User getUserInfo() throws ResourceNotFoundException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication instanceof OIDCAuthenticationToken) { if (authentication instanceof OIDCAuthenticationToken) {
return new User((OIDCAuthenticationToken) authentication); return new User((OIDCAuthenticationToken) authentication);
} }
throw new ResourceNotFoundException("No Session has been found"); 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;
}
public void revoke() {
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(revokeTokenRequest(authentication.getRefreshTokenValue()), headers);
try {
restTemplate.exchange(server.getRevocationEndpointUri(), HttpMethod.POST, entity, String.class);
} catch (Exception e) {
logger.error("Couldn't revoke refresh Tokens");
}
}
public MultiValueMap<String, String> revokeTokenRequest(String refreshToken) {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", this.client.getClientId());
map.add("client_secret", this.client.getClientSecret());
map.add("token", refreshToken);
return map;
}
} }

View File

@ -14,3 +14,6 @@ authentication.accessToken=AccessToken
authentication.redirect=http://mpagasas.di.uoa.gr:4600/reload authentication.redirect=http://mpagasas.di.uoa.gr:4600/reload
#authentication.authorities-mapper=eduperson_entitlement #authentication.authorities-mapper=eduperson_entitlement
authentication.global-vars.buildDate=@timestampLoginCore@
authentication.global-vars.version=@project.version@