Login - Logout - UserInfo

egi-login-service
parent 42fbe0b85a
commit 59772e4e86

@ -7,7 +7,6 @@
<artifactId>dnet45-parent</artifactId>
<version>1.0.0</version>
</parent>
<groupId>eu.dnetlinb</groupId>
<artifactId>login-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
@ -33,6 +32,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
@ -69,24 +73,6 @@
</exclusion>
</exclusions>
</dependency>
<!-- Json -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!--swagger official ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
<build>
<resources>

@ -0,0 +1,22 @@
package eu.dnetlib.loginservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import eu.dnetlib.loginservice.properties.Properties;
@SpringBootApplication(scanBasePackages = {"eu.dnetlib.loginservice"})
@PropertySources({
@PropertySource("classpath:application.properties"),
@PropertySource(value = "classpath:dnet-override.properties", ignoreResourceNotFound = true)
})
@EnableConfigurationProperties({Properties.class})
public class LoginServiceApplication {
public static void main(String[] args) {
SpringApplication.run(LoginServiceApplication.class, args);
}
}

@ -1,4 +1,4 @@
package eu.dnetlinb.loginservice;
package eu.dnetlib.loginservice;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@ -0,0 +1,17 @@
package eu.dnetlib.loginservice.controllers;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HealthController {
private final Logger log = Logger.getLogger(this.getClass());
@RequestMapping(value = {"", "/health_check"}, method = RequestMethod.GET)
public String hello() {
log.debug("Hello from Login service!");
return "Hello from Login service!";
}
}

@ -0,0 +1,22 @@
package eu.dnetlib.loginservice.controllers;
import eu.dnetlib.loginservice.entities.User;
import eu.dnetlib.loginservice.exception.ResourceNotFoundException;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping(value = "/userInfo", method = RequestMethod.GET)
public ResponseEntity<User> getUserInfo(Authentication authentication) {
if(authentication instanceof OIDCAuthenticationToken) {
return ResponseEntity.ok(new User((OIDCAuthenticationToken) authentication));
}
throw new ResourceNotFoundException("No Session has been found");
}
}

@ -0,0 +1,74 @@
package eu.dnetlib.loginservice.entities;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Set;
import java.util.stream.Collectors;
public class User {
private String sub;
private String name;
private String given_name;
private String family_name;
private String email;
private Set<String> roles;
public User(OIDCAuthenticationToken token) {
this.sub = token.getUserInfo().getSub();
this.name = token.getUserInfo().getName();
this.given_name = token.getUserInfo().getGivenName();
this.family_name = token.getUserInfo().getFamilyName();
this.email = token.getUserInfo().getEmail();
this.roles = token.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
}
public String getSub() {
return sub;
}
public void setSub(String sub) {
this.sub = sub;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGiven_name() {
return given_name;
}
public void setGiven_name(String given_name) {
this.given_name = given_name;
}
public String getFamily_name() {
return family_name;
}
public void setFamily_name(String family_name) {
this.family_name = family_name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Set<String> getRoles() {
return roles;
}
public void setRoles(Set<String> roles) {
this.roles = roles;
}
}

@ -0,0 +1,20 @@
package eu.dnetlib.loginservice.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND) // 404
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
public ResourceNotFoundException(String message, Throwable err) {
super(message, err);
}
public HttpStatus getStatus() {
return HttpStatus.NOT_FOUND;
}
}

@ -0,0 +1,59 @@
package eu.dnetlib.loginservice.properties;
public class OIDC {
private String issuer;
private String home;
private String id;
private String secret;
private String scope = "";
private String logout;
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getLogout() {
return logout;
}
public void setLogout(String logout) {
this.logout = logout;
}
}

@ -0,0 +1,56 @@
package eu.dnetlib.loginservice.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("authentication")
public class Properties {
private Redis redis = new Redis();
private OIDC oidc = new OIDC();
private String domain;
private String session;
private String redirect;
public Properties() {
}
public Redis getRedis() {
return redis;
}
public void setRedis(Redis redis) {
this.redis = redis;
}
public OIDC getOidc() {
return oidc;
}
public void setOidc(OIDC oidc) {
this.oidc = oidc;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getSession() {
return session;
}
public void setSession(String session) {
this.session = session;
}
public String getRedirect() {
return redirect;
}
public void setRedirect(String redirect) {
this.redirect = redirect;
}
}

@ -0,0 +1,44 @@
package eu.dnetlib.loginservice.properties;
public class Redis {
private String host = "localhost";
private String port = "6379";
private String password;
public Redis() {
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Redis{" +
"host='" + host + '\'' +
", port='" + port + '\'' +
", password='" + password + '\'' +
'}';
}
}

@ -0,0 +1,16 @@
package eu.dnetlib.loginservice.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);
}
}

@ -0,0 +1,42 @@
package eu.dnetlib.loginservice.security;
import eu.dnetlib.loginservice.properties.Properties;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@EnableRedisHttpSession
@Configuration
public class RedisConfig {
private final Properties properties;
private static final Logger logger = Logger.getLogger(RedisConfig.class);
@Autowired
public RedisConfig(Properties properties) {
this.properties = properties;
}
@Bean
public LettuceConnectionFactory connectionFactory() {
logger.info(String.format("Redis connection listens to %s:%s ", properties.getRedis().getHost(), properties.getRedis().getPort()));
LettuceConnectionFactory factory = new LettuceConnectionFactory(properties.getRedis().getHost(), Integer.parseInt(properties.getRedis().getPort()));
if (properties.getRedis().getPassword() != null) factory.setPassword(properties.getRedis().getPassword());
return factory;
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName(properties.getSession());
serializer.setCookiePath("/");
serializer.setDomainName(properties.getDomain());
return serializer;
}
}

@ -0,0 +1,82 @@
package eu.dnetlib.loginservice.security;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.security.oidc.OpenAIREAuthenticationFilter;
import eu.dnetlib.loginservice.security.oidc.OpenAIREAuthenticationSuccessHandler;
import eu.dnetlib.loginservice.security.oidc.OpenAIRELogoutHandler;
import eu.dnetlib.loginservice.security.oidc.OpenAIRELogoutSuccessHandler;
import eu.dnetlib.loginservice.utils.EntryPoint;
import org.mitre.openid.connect.client.OIDCAuthenticationProvider;
import org.mitre.openid.connect.client.service.ClientConfigurationService;
import org.mitre.openid.connect.client.service.IssuerService;
import org.mitre.openid.connect.client.service.ServerConfigurationService;
import org.mitre.openid.connect.client.service.impl.PlainAuthRequestUrlBuilder;
import org.mitre.openid.connect.client.service.impl.StaticAuthRequestOptionsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Properties properties;
private final EntryPoint entryPoint;
private final OIDCAuthenticationProvider provider;
private final IssuerService issuerService;
private final ServerConfigurationService serverConfigurationService;
private final ClientConfigurationService clientConfigurationService;
private final StaticAuthRequestOptionsService optionsService;
private final PlainAuthRequestUrlBuilder builder;
private final OpenAIREAuthenticationSuccessHandler authenticationSuccessHandler;
private final OpenAIRELogoutHandler logoutHandler;
private final OpenAIRELogoutSuccessHandler logoutSuccessHandler;
@Autowired
public WebSecurityConfig(Properties properties, EntryPoint entryPoint, OIDCAuthenticationProvider provider,
IssuerService issuerService, ServerConfigurationService serverConfigurationService,
ClientConfigurationService clientConfigurationService, StaticAuthRequestOptionsService optionsService,
PlainAuthRequestUrlBuilder builder, OpenAIREAuthenticationSuccessHandler authenticationSuccessHandler,
OpenAIRELogoutHandler logoutHandler, OpenAIRELogoutSuccessHandler logoutSuccessHandler) {
super();
this.properties = properties;
this.entryPoint = entryPoint;
this.provider = provider;
this.issuerService = issuerService;
this.serverConfigurationService = serverConfigurationService;
this.clientConfigurationService = clientConfigurationService;
this.optionsService = optionsService;
this.builder = builder;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.logoutHandler = logoutHandler;
this.logoutSuccessHandler = logoutSuccessHandler;
}
public OpenAIREAuthenticationFilter initFilter() throws Exception {
OpenAIREAuthenticationFilter filter = new OpenAIREAuthenticationFilter(properties);
filter.setAuthenticationManager(authenticationManagerBean());
filter.afterPropertiesSet();
filter.setIssuerService(issuerService);
filter.setServerConfigurationService(serverConfigurationService);
filter.setClientConfigurationService(clientConfigurationService);
filter.setAuthRequestOptionsService(optionsService);
filter.setAuthRequestUrlBuilder(builder);
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authenticationProvider(provider);
http.addFilterBefore(initFilter(), BasicAuthenticationFilter.class);
http.httpBasic().authenticationEntryPoint(entryPoint);
http.logout().logoutUrl("/openid_logout").addLogoutHandler(logoutHandler)
.logoutSuccessHandler(logoutSuccessHandler).invalidateHttpSession(false);
http.authorizeRequests().anyRequest().permitAll();
}
}

@ -0,0 +1,49 @@
package eu.dnetlib.loginservice.security.initiliazers;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.utils.ScopeReader;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;
@Configuration
public class Configurations {
private final Properties properties;
private final ScopeReader scopeReader;
@Autowired
public Configurations(Properties properties, ScopeReader scopeReader) {
this.properties = properties;
this.scopeReader = scopeReader;
}
@Bean
public ServerConfiguration serverConfiguration() {
String issuer = properties.getOidc().getIssuer();
ServerConfiguration serverConfiguration = new ServerConfiguration();
serverConfiguration.setIssuer(issuer);
serverConfiguration.setAuthorizationEndpointUri(issuer + "authorize");
serverConfiguration.setTokenEndpointUri(issuer + "token");
serverConfiguration.setUserInfoUri(issuer + "userinfo");
serverConfiguration.setJwksUri(issuer + "jwk");
serverConfiguration.setRevocationEndpointUri(issuer + "revoke");
return serverConfiguration;
}
@Bean
public RegisteredClient registeredClient() {
RegisteredClient client = new RegisteredClient();
client.setClientId(properties.getOidc().getId());
client.setClientSecret(properties.getOidc().getSecret());
client.setScope(scopeReader.getScopes());
client.setTokenEndpointAuthMethod(ClientDetailsEntity.AuthMethod.SECRET_BASIC);
client.setRedirectUris(Collections.singleton(properties.getOidc().getHome()));
return client;
}
}

@ -0,0 +1,68 @@
package eu.dnetlib.loginservice.security.initiliazers;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.security.oidc.OpenAIREAuthoritiesMapper;
import eu.dnetlib.loginservice.utils.EntryPoint;
import eu.dnetlib.loginservice.utils.ScopeReader;
import org.mitre.openid.connect.client.OIDCAuthenticationFilter;
import org.mitre.openid.connect.client.OIDCAuthenticationProvider;
import org.mitre.openid.connect.client.service.impl.PlainAuthRequestUrlBuilder;
import org.mitre.openid.connect.client.service.impl.StaticAuthRequestOptionsService;
import org.mitre.openid.connect.client.service.impl.StaticSingleIssuerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@Configuration
public class Primitives {
private final Properties properties;
private final OpenAIREAuthoritiesMapper authoritiesMapper;;
@Autowired
public Primitives(Properties properties, OpenAIREAuthoritiesMapper authoritiesMapper) {
this.properties = properties;
this.authoritiesMapper = authoritiesMapper;
}
@Bean
public ScopeReader scopeReader() {
return new ScopeReader(this.properties.getOidc().getScope());
}
@Bean
public DefaultWebSecurityExpressionHandler handler() {
return new DefaultWebSecurityExpressionHandler();
}
@Bean
public PlainAuthRequestUrlBuilder builder() {
return new PlainAuthRequestUrlBuilder();
}
@Bean
public OIDCAuthenticationProvider provider() {
OIDCAuthenticationProvider provider = new OIDCAuthenticationProvider();
provider.setAuthoritiesMapper(authoritiesMapper);
return provider;
}
@Bean
public StaticSingleIssuerService issuerService() {
StaticSingleIssuerService issuerService = new StaticSingleIssuerService();
issuerService.setIssuer(properties.getOidc().getIssuer());
return issuerService;
}
@Bean
public EntryPoint entryPoint() {
return new EntryPoint();
}
@Bean
public StaticAuthRequestOptionsService optionsService() {
return new StaticAuthRequestOptionsService();
}
}

@ -0,0 +1,48 @@
package eu.dnetlib.loginservice.security.initiliazers;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.utils.ScopeReader;
import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.client.service.impl.StaticClientConfigurationService;
import org.mitre.openid.connect.client.service.impl.StaticServerConfigurationService;
import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class Services {
private final Properties properties;
private final ServerConfiguration serverConfiguration;
private final RegisteredClient clientConfiguration;
@Autowired
public Services(Properties properties, ServerConfiguration serverConfiguration, RegisteredClient clientConfiguration) {
this.properties = properties;
this.serverConfiguration = serverConfiguration;
this.clientConfiguration = clientConfiguration;
}
@Bean
public StaticServerConfigurationService serverConfigurationService() {
StaticServerConfigurationService configurationService = new StaticServerConfigurationService();
Map<String, ServerConfiguration> servers = new HashMap<>();
servers.put(properties.getOidc().getIssuer(), serverConfiguration);
configurationService.setServers(servers);
return configurationService;
}
@Bean
public StaticClientConfigurationService clientConfigurationService() {
StaticClientConfigurationService configurationService = new StaticClientConfigurationService();
Map<String, RegisteredClient> clients = new HashMap<>();
clients.put(properties.getOidc().getIssuer(), clientConfiguration);
configurationService.setClients(clients);
return configurationService;
}
}

@ -0,0 +1,27 @@
package eu.dnetlib.loginservice.security.oidc;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.utils.Redirect;
import org.apache.log4j.Logger;
import org.mitre.openid.connect.client.OIDCAuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OpenAIREAuthenticationFilter extends OIDCAuthenticationFilter {
private final static Logger logger = Logger.getLogger(OpenAIREAuthenticationSuccessHandler.class);
private final Properties properties;
public OpenAIREAuthenticationFilter(Properties properties) {
super();
this.properties = properties;
}
@Override
protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
Redirect.setRedirect(request, properties);
super.handleAuthorizationRequest(request, response);
}
}

@ -0,0 +1,65 @@
package eu.dnetlib.loginservice.security.oidc;
import com.google.gson.JsonParser;
import eu.dnetlib.loginservice.properties.Properties;
import org.apache.log4j.Logger;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.session.FindByIndexNameSessionRepository;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Base64;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Configuration
public class OpenAIREAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger logger = Logger.getLogger(OpenAIREAuthenticationSuccessHandler.class);
private final Properties properties;
@Autowired
public OpenAIREAuthenticationSuccessHandler(Properties properties) {
this.properties = properties;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication;
HttpSession session = request.getSession();
String redirect = (String) session.getAttribute("redirect");
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, token.getUserInfo().getSub());
try {
Cookie accessToken = new Cookie("AccessToken", token.getAccessTokenValue());
String regex = "^([A-Za-z0-9-_=]+)\\.([A-Za-z0-9-_=]+)\\.?([A-Za-z0-9-_.+=]*)$";
Matcher matcher = Pattern.compile(regex).matcher(token.getAccessTokenValue());
if (matcher.find()) {
long exp = new JsonParser().parse(new String(Base64.getDecoder().decode(matcher.group(2)))).getAsJsonObject().get("exp").getAsLong();
accessToken.setMaxAge((int) (exp - (new Date().getTime() / 1000)));
} else {
accessToken.setMaxAge(3600);
}
accessToken.setPath("/");
accessToken.setDomain(properties.getDomain());
response.addCookie(accessToken);
if(redirect != null) {
response.sendRedirect(redirect);
session.removeAttribute("redirect");
} else {
response.sendRedirect(properties.getRedirect());
}
} catch (IOException e) {
logger.error("IOException in redirection ", e);
throw new IOException(e);
}
}
}

@ -0,0 +1,21 @@
package eu.dnetlib.loginservice.security.oidc;
import com.google.gson.JsonArray;
import com.nimbusds.jwt.JWT;
import eu.dnetlib.loginservice.utils.AuthoritiesMapper;
import org.mitre.openid.connect.client.OIDCAuthoritiesMapper;
import org.mitre.openid.connect.model.UserInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class OpenAIREAuthoritiesMapper implements OIDCAuthoritiesMapper {
@Override
public Collection<? extends GrantedAuthority> mapAuthorities(JWT jwtToken, UserInfo userInfo) {
JsonArray entitlements = userInfo.getSource().getAsJsonArray("edu_person_entitlements");
return AuthoritiesMapper.map(entitlements);
}
}

@ -0,0 +1,27 @@
package eu.dnetlib.loginservice.security.oidc;
import eu.dnetlib.loginservice.properties.Properties;
import eu.dnetlib.loginservice.utils.Redirect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Service
public class OpenAIRELogoutHandler implements LogoutHandler {
private Properties properties;
@Autowired
public OpenAIRELogoutHandler(Properties properties) {
this.properties = properties;
}
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
Redirect.setRedirect(request, properties);
}
}

@ -0,0 +1,37 @@
package eu.dnetlib.loginservice.security.oidc;
import eu.dnetlib.loginservice.properties.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Collectors;
@Configuration
public class OpenAIRELogoutSuccessHandler implements LogoutSuccessHandler {
private final Properties properties;
@Autowired
public OpenAIRELogoutSuccessHandler(Properties properties) {
this.properties = properties;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
HttpSession session = request.getSession();
String redirect = (String) session.getAttribute("redirect");
session.removeAttribute("redirect");
if(redirect == null) {
redirect = properties.getRedirect();
}
session.invalidate();
response.sendRedirect(properties.getOidc().getLogout() + redirect);
}
}

@ -0,0 +1,41 @@
package eu.dnetlib.loginservice.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import org.apache.log4j.Logger;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AuthoritiesMapper {
private static final Logger logger = Logger.getLogger(AuthoritiesMapper.class);
public static Collection<? extends GrantedAuthority> map(JsonArray entitlements) {
HashSet<SimpleGrantedAuthority> authorities = new HashSet<>();
String regex = "urn:geant:openaire[.]eu:group:([^:]*):?(.*)?:role=member#aai[.]openaire[.]eu";
for(JsonElement obj: entitlements) {
Matcher matcher = Pattern.compile(regex).matcher(obj.getAsString());
if (matcher.find()) {
StringBuilder sb = new StringBuilder();
if(matcher.group(1) != null && matcher.group(1).length() > 0) {
sb.append(matcher.group(1).replace("+-+", "_").replaceAll("[+.]", "_").toUpperCase());
}
if(matcher.group(2).length() > 0) {
sb.append("_");
if(matcher.group(2).equals("admins")) {
sb.append("MANAGER");
} else {
sb.append(matcher.group(2).toUpperCase());
}
}
authorities.add(new SimpleGrantedAuthority(sb.toString()));
}
}
return authorities;
}
}

@ -0,0 +1,19 @@
package eu.dnetlib.loginservice.utils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class EntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}
}

@ -0,0 +1,39 @@
package eu.dnetlib.loginservice.utils;
import eu.dnetlib.loginservice.properties.Properties;
import org.apache.http.client.utils.URIBuilder;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URISyntaxException;
import java.util.Enumeration;
public class Redirect {
private final static Logger logger = Logger.getLogger(Redirect.class);
private static String getDomain(String url) throws URISyntaxException {
URIBuilder uriBuilder = new URIBuilder(url);
return uriBuilder.getHost();
}
public static void setRedirect(HttpServletRequest request, Properties properties) {
HttpSession session = request.getSession();
Enumeration<String> params = request.getParameterNames();
while (params.hasMoreElements()) {
String param = params.nextElement();
if(param.equalsIgnoreCase("redirect")) {
String redirect = request.getParameter(param);
try {
if(getDomain(redirect).endsWith(properties.getDomain())) {
session.setAttribute("redirect", redirect);
}
} catch (URISyntaxException e) {
logger.error(e.getMessage());
}
}
}
}
}

@ -0,0 +1,25 @@
package eu.dnetlib.loginservice.utils;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ScopeReader {
Set<String> scopes;
public ScopeReader(String property) {
if (!property.trim().isEmpty()){
scopes = new HashSet<>();
Collections.addAll(scopes, property.split(","));
}
}
public Set<String> getScopes() {
return scopes;
}
public void setScopes(Set<String> scopes) {
this.scopes = scopes;
}
}

@ -1,13 +0,0 @@
package eu.dnetlinb.loginservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LoginServiceApplication {
public static void main(String[] args) {
SpringApplication.run(LoginServiceApplication.class, args);
}
}

@ -1 +1,9 @@
authentication.domain=di.uoa.gr
authentication.oidc.issuer=https://aai.openaire.eu/oidc/
authentication.oidc.logout=https://aai.openaire.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo=
authentication.oidc.home=http://mpagasas.di.uoa.gr:8090/openid_connect_login
authentication.oidc.scope=openid,profile,email,eduperson_entitlement
authentication.oidc.id=id
authentication.oidc.secret=secret
authentication.session=openAIRESession
authentication.redirect=http://mpagasas.di.uoa.gr:4600/reload

@ -0,0 +1,20 @@
log4j.rootLogger = DEBUG, R
log4j.logger.eu.dnetlib = DEBUG
log4j.logger.org.springframework = DEBUG, S
log4j.additivity.org.springframework = false
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/var/log/dnet/login-service/login-service.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern= %d %p %t [%c] - %m%n
log4j.appender.S=org.apache.log4j.RollingFileAppender
log4j.appender.S.File=/var/log/dnet/login-service/login-service-spring.log
log4j.appender.S.MaxFileSize=10MB
log4j.appender.S.MaxBackupIndex=10
log4j.appender.S.layout=org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern= %d %p %t [%c] - %m%n

@ -1,4 +1,4 @@
package eu.dnetlinb.loginservice;
package eu.dnetlib.loginservice;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
Loading…
Cancel
Save