Adds configurable login providers

This commit is contained in:
gkolokythas 2019-11-13 17:32:55 +02:00
parent caefd0ccc5
commit e63eb8f205
33 changed files with 782 additions and 17 deletions

View File

@ -3,10 +3,15 @@ package eu.eudat.controllers;
import eu.eudat.core.logger.Logger;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.managers.UserManager;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.logic.security.CustomAuthenticationProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.models.ConfigurableProvidersModel;
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest;
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator;
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest;
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken;
@ -45,6 +50,8 @@ public class Login {
private ORCIDTokenValidator orcidTokenValidator;
private LinkedInTokenValidator linkedInTokenValidator;
private OpenAIRETokenValidator openAIRETokenValidator;
private ConfigurableProviderTokenValidator configurableProviderTokenValidator;
private ConfigLoader configLoader;
private Logger logger;
@ -52,7 +59,7 @@ public class Login {
@Autowired
public Login(CustomAuthenticationProvider customAuthenticationProvider, AuthenticationService nonVerifiedUserAuthenticationService,
TwitterTokenValidator twitterTokenValidator, LinkedInTokenValidator linkedInTokenValidator, B2AccessTokenValidator b2AccessTokenValidator,
ORCIDTokenValidator orcidTokenValidator, OpenAIRETokenValidator openAIRETokenValidator, UserManager userManager, Logger logger) {
ORCIDTokenValidator orcidTokenValidator, OpenAIRETokenValidator openAIRETokenValidator, ConfigurableProviderTokenValidator configurableProviderTokenValidator, ConfigLoader configLoader, UserManager userManager, Logger logger) {
this.customAuthenticationProvider = customAuthenticationProvider;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.twitterTokenValidator = twitterTokenValidator;
@ -60,6 +67,8 @@ public class Login {
this.b2AccessTokenValidator = b2AccessTokenValidator;
this.orcidTokenValidator = orcidTokenValidator;
this.openAIRETokenValidator = openAIRETokenValidator;
this.configurableProviderTokenValidator = configurableProviderTokenValidator;
this.configLoader = configLoader;
this.logger = logger;
this.userManager = userManager;
}
@ -110,6 +119,12 @@ public class Login {
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<OpenAIREResponseToken>().payload(this.openAIRETokenValidator.getAccessToken(openAIRERequest)).status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.POST, value = {"/configurableProviderRequestToken"}, produces = "application/json", consumes = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<ConfigurableProviderResponseToken>> configurableProviderRequestToken(@RequestBody ConfigurableProviderRequest configurableProviderRequest) {
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<ConfigurableProviderResponseToken>().payload(this.configurableProviderTokenValidator.getAccessToken(configurableProviderRequest)).status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Principal>> authMe(Principal principal) throws NullEmailException {
@ -125,4 +140,10 @@ public class Login {
this.logger.info(principal, "Logged Out");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.GET, value = {"/configurableLogin"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<ConfigurableProvidersModel>> getConfigurableProviders() {
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<ConfigurableProvidersModel>().payload(new ConfigurableProvidersModel().fromDataModel(configLoader.getConfigurableProviders())).status(ApiMessageCode.NO_MESSAGE));
}
}

View File

@ -3,7 +3,6 @@ package eu.eudat.logic.managers;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.dao.entities.UserInfoDao;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.UserDMP;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.UserRole;
import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem;

View File

@ -1,6 +1,7 @@
package eu.eudat.logic.proxy.config.configloaders;
import eu.eudat.logic.proxy.config.ExternalUrls;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.util.List;
@ -9,4 +10,5 @@ public interface ConfigLoader {
ExternalUrls getExternalUrls();
List<String> getRdaProperties();
XWPFDocument getDocument();
ConfigurableProviders getConfigurableProviders();
}

View File

@ -1,6 +1,9 @@
package eu.eudat.logic.proxy.config.configloaders;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.proxy.config.ExternalUrls;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
@ -24,6 +27,7 @@ public class DevelConfigLoader implements ConfigLoader {
private ExternalUrls externalUrls;
private List<String> rdaProperties;
private XWPFDocument document;
private ConfigurableProviders configurableProviders;
@Autowired
private Environment environment;
@ -40,7 +44,6 @@ public class DevelConfigLoader implements ConfigLoader {
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
is = new URL("file:///" + current + fileUrl).openStream();
externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Cannot find in folder" + current);
@ -77,12 +80,39 @@ public class DevelConfigLoader implements ConfigLoader {
private void setDocument() {
String filePath = environment.getProperty("configuration.h2020template");
String current = null;
InputStream is = null;
try {
current = new java.io.File(".").getCanonicalPath();
InputStream is = new URL("file:///" + current + filePath).openStream();
is = new URL("file:///" + current + filePath).openStream();
this.document = new XWPFDocument(is);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) is.close();
} catch (IOException e) {
System.out.println("Warning: Could not close a stream after reading from file: " + filePath);
}
}
}
public void setConfigurableProviders() {
String filePath = environment.getProperty("configuration.configurable_login_providers");
String current = null;
InputStream is = null;
try {
current = new java.io.File(".").getCanonicalPath();
is = new URL("file:///" + current + filePath).openStream();
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configurableProviders = mapper.readValue(is, ConfigurableProviders.class);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) is.close();
} catch (IOException e) {
System.out.println("Warning: Could not close a stream after reading from file: " + filePath);
}
}
}
@ -100,4 +130,9 @@ public class DevelConfigLoader implements ConfigLoader {
this.setDocument();
return document;
}
public ConfigurableProviders getConfigurableProviders() {
this.setConfigurableProviders();
return configurableProviders;
}
}

View File

@ -1,6 +1,8 @@
package eu.eudat.logic.proxy.config.configloaders;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.proxy.config.ExternalUrls;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
@ -25,6 +27,7 @@ public class ProductionConfigLoader implements ConfigLoader {
private ExternalUrls externalUrls;
private List<String> rdaProperties;
private XWPFDocument document;
private ConfigurableProviders configurableProviders;
@Autowired
private Environment environment;
@ -85,6 +88,19 @@ public class ProductionConfigLoader implements ConfigLoader {
}
}
public void setConfigurableProviders() {
String filePath = environment.getProperty("configuration.configurable_login_providers");
String current = null;
try {
current = new java.io.File(".").getCanonicalPath();
InputStream is = new URL(Paths.get(filePath).toUri().toURL().toString()).openStream();
ObjectMapper objectMapper = new ObjectMapper();
this.configurableProviders = objectMapper.readValue(is, ConfigurableProviders.class);
} catch (IOException e) {
e.printStackTrace();
}
}
public ExternalUrls getExternalUrls() {
this.setExternalUrls();
return externalUrls;
@ -99,4 +115,9 @@ public class ProductionConfigLoader implements ConfigLoader {
this.setDocument();
return document;
}
public ConfigurableProviders getConfigurableProviders() {
this.setConfigurableProviders();
return configurableProviders;
}
}

View File

@ -0,0 +1,11 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
public interface ConfigurableProviderCustomProvider {
ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl, String grantType, String access_token, String expires_in);
ConfigurableProviderUser getUser(String accessToken, ConfigurableProviderUserSettings user);
}

View File

@ -0,0 +1,59 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Component("configurableProviderCustomProvider")
public class ConfigurableProviderCustomProviderImpl implements ConfigurableProviderCustomProvider {
@Override
public ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl,
String grantType, String access_token, String expires_in) {
RestTemplate template = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("grant_type", grantType);
map.add("code", code);
map.add("redirect_uri", redirectUri);
map.add("client_id", clientId);
map.add("client_secret", clientSecret);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
Map<String, Object> values = template.postForObject(accessTokenUrl, request, Map.class);
ConfigurableProviderResponseToken responseToken = new ConfigurableProviderResponseToken();
responseToken.setAccessToken((String) values.get(access_token));
responseToken.setExpiresIn((Integer) values.get(expires_in));
return responseToken;
}
@Override
public ConfigurableProviderUser getUser(String accessToken, ConfigurableProviderUserSettings user) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = this.createBearerAuthHeaders(accessToken);
HttpEntity<String> entity = new HttpEntity<>(headers);
Map<String, Object> values = restTemplate.exchange(user.getUser_info_url(), HttpMethod.GET, entity, Map.class).getBody();
return new ConfigurableProviderUser().getConfigurableProviderUser(values, user);
}
private HttpHeaders createBearerAuthHeaders(String accessToken) {
return new HttpHeaders() {{
String authHeader = "Bearer " + accessToken;
set("Authorization", authHeader);
}};
}
}

View File

@ -0,0 +1,39 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings;
import java.util.Map;
public class ConfigurableProviderUser {
private String id;
private String name;
private String email;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
ConfigurableProviderUser getConfigurableProviderUser(Map data, ConfigurableProviderUserSettings user) {
this.id = (String) data.get(user.getId());
this.name = (String) data.get(user.getName());
this.email = (String) data.get(user.getEmail());
return this;
}
}

View File

@ -0,0 +1,109 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities;
public class ConfigurableProvider {
private boolean enabled;
private String configurableLoginId;
private String name;
private String clientId;
private String clientSecret;
private String redirect_uri;
private String access_token_url;
private String grant_type;
private ConfigurableProviderToken token;
private ConfigurableProviderUserSettings user;
private String oauthUrl;
private String scope;
private String state;
public boolean getEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getConfigurableLoginId() {
return configurableLoginId;
}
public void setConfigurableLoginId(String configurableLoginId) {
this.configurableLoginId = configurableLoginId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getRedirect_uri() {
return redirect_uri;
}
public void setRedirect_uri(String redirect_uri) {
this.redirect_uri = redirect_uri;
}
public String getAccess_token_url() {
return access_token_url;
}
public void setAccess_token_url(String access_token_url) {
this.access_token_url = access_token_url;
}
public String getGrant_type() {
return grant_type;
}
public void setGrant_type(String grant_type) {
this.grant_type = grant_type;
}
public ConfigurableProviderToken getToken() {
return token;
}
public void setToken(ConfigurableProviderToken token) {
this.token = token;
}
public ConfigurableProviderUserSettings getUser() {
return user;
}
public void setUser(ConfigurableProviderUserSettings user) {
this.user = user;
}
public String getOauthUrl() {
return oauthUrl;
}
public void setOauthUrl(String oauthUrl) {
this.oauthUrl = oauthUrl;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}

View File

@ -0,0 +1,20 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities;
public class ConfigurableProviderToken {
private String access_token;
private String expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
}

View File

@ -0,0 +1,36 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities;
public class ConfigurableProviderUserSettings {
private String id;
private String name;
private String email;
private String user_info_url;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUser_info_url() {
return user_info_url;
}
public void setUser_info_url(String user_info_url) {
this.user_info_url = user_info_url;
}
}

View File

@ -0,0 +1,15 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities;
import java.util.ArrayList;
import java.util.List;
public class ConfigurableProviders {
private List<ConfigurableProvider> providers = new ArrayList<>();
public List<ConfigurableProvider> getProviders() {
return providers;
}
public void setProviders(List<ConfigurableProvider> providers) {
this.providers = providers;
}
}

View File

@ -0,0 +1,76 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.models;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider;
public class ConfigurableProviderModel {
private String configurableLoginId;
private String name;
private String clientId;
private String redirect_uri;
private String oauthUrl;
private String scope;
private String state;
public String getConfigurableLoginId() {
return configurableLoginId;
}
public void setConfigurableLoginId(String configurableLoginId) {
this.configurableLoginId = configurableLoginId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getRedirect_uri() {
return redirect_uri;
}
public void setRedirect_uri(String redirect_uri) {
this.redirect_uri = redirect_uri;
}
public String getOauthUrl() {
return oauthUrl;
}
public void setOauthUrl(String oauthUrl) {
this.oauthUrl = oauthUrl;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public ConfigurableProviderModel fromDataModel(ConfigurableProvider entity) {
ConfigurableProviderModel model = new ConfigurableProviderModel();
model.setConfigurableLoginId(entity.getConfigurableLoginId());
model.setName(entity.getName());
model.setClientId(entity.getClientId());
model.setRedirect_uri(entity.getRedirect_uri());
model.setOauthUrl(entity.getOauthUrl());
model.setScope(entity.getScope());
model.setState(entity.getState());
return model;
}
}

View File

@ -0,0 +1,29 @@
package eu.eudat.logic.security.customproviders.ConfigurableProvider.models;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import java.util.LinkedList;
import java.util.List;
public class ConfigurableProvidersModel {
private List<ConfigurableProviderModel> providers;
public List<ConfigurableProviderModel> getProviders() {
return providers;
}
public void setProviders(List<ConfigurableProviderModel> providers) {
this.providers = providers;
}
public ConfigurableProvidersModel fromDataModel(ConfigurableProviders entity) {
ConfigurableProvidersModel model = new ConfigurableProvidersModel();
List<ConfigurableProviderModel> providerModelList = new LinkedList<>();
for (ConfigurableProvider entityProvider : entity.getProviders()) {
if (entityProvider.getEnabled())
providerModelList.add(new ConfigurableProviderModel().fromDataModel(entityProvider));
}
model.setProviders(providerModelList);
return model;
}
}

View File

@ -1,10 +1,13 @@
package eu.eudat.logic.security.validators;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider;
import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider;
import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider;
import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider;
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator;
import eu.eudat.logic.security.validators.facebook.FacebookTokenValidator;
import eu.eudat.logic.security.validators.google.GoogleTokenValidator;
import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator;
@ -20,7 +23,7 @@ import org.springframework.stereotype.Service;
@Service("tokenValidatorFactory")
public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
public enum LoginProvider {
GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7), OPENAIRE(8);
GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7), OPENAIRE(8), CONFIGURABLE(9);
private int value;
@ -50,6 +53,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
return ORCID;
case 8:
return OPENAIRE;
case 9:
return CONFIGURABLE;
default:
throw new RuntimeException("Unsupported LoginProvider");
}
@ -62,18 +67,22 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
private ORCIDCustomProvider orcidCustomProvider;
private LinkedInCustomProvider linkedInCustomProvider;
private OpenAIRECustomProvider openAIRECustomProvider;
private ConfigurableProviderCustomProvider configurableProviderCustomProvider;
private ConfigLoader configLoader;
@Autowired
public TokenValidatorFactoryImpl(
Environment environment,
AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider,
ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider, OpenAIRECustomProvider openAIRECustomProvider) {
ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider, OpenAIRECustomProvider openAIRECustomProvider, ConfigurableProviderCustomProvider configurableProviderCustomProvider, ConfigLoader configLoader) {
this.environment = environment;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.b2AccessCustomProvider = b2AccessCustomProvider;
this.orcidCustomProvider = orcidCustomProvider;
this.linkedInCustomProvider = linkedInCustomProvider;
this.openAIRECustomProvider = openAIRECustomProvider;
this.configurableProviderCustomProvider = configurableProviderCustomProvider;
this.configLoader = configLoader;
}
public TokenValidator getProvider(LoginProvider provider) {
@ -92,6 +101,8 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider);
case OPENAIRE:
return new OpenAIRETokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.openAIRECustomProvider);
case CONFIGURABLE:
return new ConfigurableProviderTokenValidator(this.configurableProviderCustomProvider, this.nonVerifiedUserAuthenticationService, this.configLoader);
default:
throw new RuntimeException("Login Provider Not Implemented");
}

View File

@ -0,0 +1,60 @@
package eu.eudat.logic.security.validators.configurableProvider;
import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderUser;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import org.springframework.stereotype.Component;
import java.util.stream.Collectors;
@Component("configurableProviderTokenValidator")
public class ConfigurableProviderTokenValidator implements TokenValidator {
private ConfigurableProviderCustomProvider configurableProvider;
private AuthenticationService nonVerifiedUserAuthenticationService;
private ConfigLoader configLoader;
public ConfigurableProviderTokenValidator(ConfigurableProviderCustomProvider configurableProvider, AuthenticationService nonVerifiedUserAuthenticationService, ConfigLoader configLoader) {
this.configurableProvider = configurableProvider;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
this.configLoader = configLoader;
}
public ConfigurableProviderResponseToken getAccessToken(ConfigurableProviderRequest configurableProviderRequest) {
ConfigurableProvider provider = getConfigurableProviderFromId(configurableProviderRequest.getConfigurableLoginId());
return this.configurableProvider.getAccessToken(configurableProviderRequest.getCode(),
provider.getRedirect_uri(), provider.getClientId(), provider.getClientSecret(),
provider.getAccess_token_url(), provider.getGrant_type(), provider.getToken().getAccess_token(), provider.getToken().getExpires_in());
}
@Override
public Principal validateToken(LoginInfo credentials) throws NullEmailException {
String configurableLoginId = (String) credentials.getData();
ConfigurableProvider configurableProvider = getConfigurableProviderFromId(configurableLoginId);
ConfigurableProviderUser configurableUser = this.configurableProvider.getUser(credentials.getTicket(), configurableProvider.getUser());
LoginProviderUser user = new LoginProviderUser();
user.setId(configurableUser.getId());
user.setEmail(configurableUser.getEmail());
user.setName(configurableUser.getName());
user.setProvider(credentials.getProvider());
user.setSecret(credentials.getTicket());
return this.nonVerifiedUserAuthenticationService.Touch(user);
}
private ConfigurableProvider getConfigurableProviderFromId(String configurableId) {
return this.configLoader.getConfigurableProviders().getProviders().stream()
.filter(prov -> prov.getConfigurableLoginId().equals(configurableId))
.collect(Collectors.toList())
.get(0);
}
}

View File

@ -0,0 +1,20 @@
package eu.eudat.logic.security.validators.configurableProvider.helpers;
public class ConfigurableProviderRequest {
private String code;
private String configurableLoginId;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getConfigurableLoginId() {
return configurableLoginId;
}
public void setConfigurableLoginId(String configurableLoginId) {
this.configurableLoginId = configurableLoginId;
}
}

View File

@ -0,0 +1,20 @@
package eu.eudat.logic.security.validators.configurableProvider.helpers;
public class ConfigurableProviderResponseToken {
private String accessToken;
private Integer expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public Integer getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(Integer expiresIn) {
this.expiresIn = expiresIn;
}
}

View File

@ -18,6 +18,7 @@ pdf.converter.url=http://localhost:88/
configuration.externalUrls=/web/src/main/resources/ExternalUrls.xml
configuration.rda=/web/src/main/resources/RDACommonStandards.txt
configuration.h2020template=/web/src/main/resources/documents/h2020.docx
configuration.configurable_login_providers=/web/src/main/resources/configurableLoginProviders.json
#############TWITTER LOGIN CONFIGURATIONS#########

View File

@ -19,6 +19,7 @@ pdf.converter.url=http://docsbox-web/
configuration.externalUrls=/tmp/ExternalUrls.xml
configuration.rda=/tmp/RDACommonStandards.txt
configuration.h2020template=/tmp/h2020.docx
configuration.configurable_login_providers=
####################SPRING MAIL CONFIGURATIONS#################
spring.mail.default-encoding=UTF-8

View File

@ -19,6 +19,7 @@ pdf.converter.url=http://docsbox-web/
configuration.externalUrls=/tmp/ExternalUrls.xml
configuration.rda=/tmp/RDACommonStandards.txt
configuration.h2020template=tmp/h2020.docx
configuration.configurable_login_providers=
####################INVITATION MAIL CONFIGURATIONS##############
####################GENERIC MAIL CONFIGURATIONS#################
@ -76,7 +77,6 @@ openaire.login.client_id=
openaire.login.client_secret=
openaire.login.access_token_url=
openaire.login.redirect_uri=
openaire.login.userinfo_endpoint=
#############ZENODO CONFIGURATIONS#########
zenodo.url=https://sandbox.zenodo.org/api/

View File

@ -23,6 +23,7 @@ spring.mail.properties.mail.smtp.starttls.enable=false
configuration.externalUrls=
configuration.rda=
configuration.h2020template=
configuration.configurable_login_providers=
#############LOGIN CONFIGURATIONS#########
#############GENERIC LOGIN CONFIGURATIONS#########

View File

@ -0,0 +1,27 @@
{
"providers": [
{
"enabled": true,
"configurableLoginId": "myId",
"name": "myApp",
"clientId": "",
"clientSecret": "",
"redirect_uri": "",
"access_token_url": "",
"grant_type": "authorization_code",
"token": {
"access_token": "access_token",
"expires_in": "expires_in"
},
"user": {
"id": "sub",
"name": "name",
"email": "email",
"user_info_endpoint": ""
},
"oauthUrl": "/authorize",
"scope": "email",
"state": "123562"
}
]
}

View File

@ -6,5 +6,6 @@ export enum AuthProvider {
//NativeLogin=5,
B2Access = 6,
ORCID = 7,
OpenAire = 8
OpenAire = 8,
Configurable = 9
}

View File

@ -0,0 +1,9 @@
export class ConfigurableProvider {
configurableLoginId: string;
name: string;
clientId: string;
redirect_uri: string;
oauthUrl: string;
scope: string;
state: string;
}

View File

@ -1,7 +1,7 @@
import {of as observableOf, throwError as observableThrowError, Observable } from 'rxjs';
import { of as observableOf, throwError as observableThrowError, Observable } from 'rxjs';
import {map, catchError, takeUntil } from 'rxjs/operators';
import { map, catchError, takeUntil } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
@ -14,6 +14,7 @@ import { Credential } from '../../model/auth/credential';
import { LoginInfo } from '../../model/auth/login-info';
import { Principal } from '../../model/auth/Principal';
import { UiNotificationService, SnackBarNotificationLevel } from '../notification/ui-notification-service';
import { ConfigurableProvider } from "../../model/configurable-provider/configurableProvider";
@Injectable()
@ -78,7 +79,7 @@ export class AuthService extends BaseService {
catchError((error: any) => {
//this.loginContextSubject.next(false);
return observableThrowError(error);
}),);
}));
}
public nativeLogin(credentials: Credential): Observable<Principal> {
@ -93,7 +94,7 @@ export class AuthService extends BaseService {
catchError((error: any) => {
//this.loginContextSubject.next(false);
return observableThrowError(error);
}),);
}));
}
@ -133,7 +134,7 @@ export class AuthService extends BaseService {
const princ = this.current();
this.router.navigate(['/login']);
return observableOf<Principal>(princ);
}),);
}));
}
public onLogOutSuccess(logoutMessage: any) {
@ -145,4 +146,14 @@ export class AuthService extends BaseService {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Error);
this.router.navigate(['/login']);
}
public getConfigurableProviders(): Observable<ConfigurableProvider[]> {
const url = this.actionUrl + 'configurableLogin';
return this.http.get<ConfigurableProvider[]>(url, { headers: this.headers }).pipe(
map((res: any) => {
const providers = res.payload.providers;
return providers;
})
);
}
}

View File

@ -0,0 +1,93 @@
import { Component, OnInit, Input } from "@angular/core";
import { BaseComponent } from "../../../../core/common/base/base.component";
import { ActivatedRoute, Router, Params } from "@angular/router";
import { HttpClient } from "@angular/common/http";
import { LoginService } from "../utilities/login.service";
import { AuthService } from "../../../../core/services/auth/auth.service";
import { takeUntil } from "rxjs/operators";
import { environment } from "../../../../../environments/environment";
import { AuthProvider } from "../../../../core/common/enum/auth-provider";
import { ConfigurableProvider } from "../../../../core/model/configurable-provider/configurableProvider";
import { ConfigurableProvidersService } from "../utilities/configurableProviders.service";
@Component({
selector: 'app-configurable-login',
templateUrl: './configurable-login.component.html',
})
export class ConfigurableLoginComponent extends BaseComponent implements OnInit {
private returnUrl: string;
// private configurableLoginId: string;
// private clientId: string;
// private oauthUrl: string;
// private redirectUri: string;
// private state: string;
// @Input() scope: string;
private provider: ConfigurableProvider;
private providerId: string;
constructor(
private route: ActivatedRoute,
private loginService: LoginService,
private authService: AuthService,
private router: Router,
private httpClient: HttpClient,
private providers: ConfigurableProvidersService
) {
super();
}
ngOnInit(): void {
const params = this.route.snapshot.params;
this.providerId = params['id'];
if (this.providers.providers === undefined) {
this.authService.getConfigurableProviders()
.pipe(takeUntil(this._destroyed))
.subscribe((data) => {
this.providers.providers = data;
this.provider = this.providers.providers.find(item => item.configurableLoginId == this.providerId)
this.route.queryParams
.pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => {
const returnUrlFromParams = params['returnUrl'];
if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; }
if (!params['code']) { this.configurableAuthorize(); } else { this.configurableLoginUser(params['code'], params['state']) }
})
});
} else {
this.provider = this.providers.providers.find(item => item.configurableLoginId == this.providerId)
this.route.queryParams
.pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => {
const returnUrlFromParams = params['returnUrl'];
if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; }
if (!params['code']) { this.configurableAuthorize(); } else { this.configurableLoginUser(params['code'], params['state']) }
})
}
}
public configurableAuthorize() {
window.location.href = this.provider.oauthUrl
+ '?response_type=code&client_id=' + this.provider.clientId
+ '&redirect_uri=' + this.provider.redirect_uri + this.providerId
+ '&state=' + this.provider.state
+ '&scope=' + this.provider.scope;
}
public configurableLoginUser(code: string, state: string) {
if (state !== this.provider.state) {
this.router.navigate(['/login'])
}
this.httpClient.post(environment.Server + 'auth/configurableProviderRequestToken', { code: code, provider: AuthProvider.Configurable, configurableLoginId: this.providerId })
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.Configurable, data: { configurableLoginId: this.provider.configurableLoginId } })
.pipe(takeUntil(this._destroyed))
.subscribe(
res => this.loginService.onLogInSuccess(res, this.returnUrl),
error => this.loginService.onLogInError(error)
)
})
}
}

View File

@ -47,6 +47,11 @@
</div>
<!-- </div> -->
</div>
<div *ngFor="let provider of this.configurableProviderService.providers">
<button mat-icon-button (click)="configurableLogin(provider)" class="login-social-button">
{{provider.name}}
</button>
</div>
</div>
<div class="card-footer">
<h4 class="text-uppercase">

View File

@ -6,6 +6,8 @@ import { BaseComponent } from '../../../core/common/base/base.component';
import { AuthProvider } from '../../../core/common/enum/auth-provider';
import { AuthService } from '../../../core/services/auth/auth.service';
import { LoginService } from './utilities/login.service';
import { ConfigurableProvider } from "../../../core/model/configurable-provider/configurableProvider";
import { ConfigurableProvidersService } from "./utilities/configurableProviders.service";
/// <reference types="gapi" />
/// <reference types="facebook-js-sdk" />
@ -21,12 +23,14 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn
public auth2: any;
private returnUrl: string;
//public cofigurableProviders: ConfigurableProvider[];
constructor(
private router: Router,
private route: ActivatedRoute,
private loginService: LoginService,
private authService: AuthService
private authService: AuthService,
public configurableProviderService: ConfigurableProvidersService
) { super(); }
ngOnInit(): void {
@ -36,6 +40,11 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn
const returnUrl = params['returnUrl'];
if (returnUrl) { this.returnUrl = returnUrl; }
});
this.authService.getConfigurableProviders()
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.configurableProviderService.providers = data;
})
}
ngAfterViewInit() {
@ -62,6 +71,10 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn
this.router.navigate(['/login/openaire']);
}
public configurableLogin(provider: ConfigurableProvider) {
this.router.navigate(['/login/configurable/' + provider.configurableLoginId])
}
public hasFacebookOauth(): boolean {
return this.hasProvider(AuthProvider.Facebook);
}

View File

@ -10,6 +10,8 @@ import { B2AccessLoginComponent } from './b2access/b2access-login.component';
import { OrcidLoginComponent } from './orcid-login/orcid-login.component';
import { EmailConfirmation } from './email-confirmation/email-confirmation.component';
import { OpenAireLoginComponent } from "./openaire-login/openaire-login.component";
import { ConfigurableLoginComponent } from "./configurable-login/configurable-login.component";
import { ConfigurableProvidersService } from "./utilities/configurableProviders.service";
@NgModule({
imports: [
@ -24,8 +26,9 @@ import { OpenAireLoginComponent } from "./openaire-login/openaire-login.componen
B2AccessLoginComponent,
OrcidLoginComponent,
EmailConfirmation,
OpenAireLoginComponent
OpenAireLoginComponent,
ConfigurableLoginComponent
],
providers: [LoginService]
providers: [LoginService, ConfigurableProvidersService]
})
export class LoginModule { }

View File

@ -7,6 +7,7 @@ import { LoginComponent } from './login.component';
import { OrcidLoginComponent } from './orcid-login/orcid-login.component';
import { TwitterLoginComponent } from './twitter-login/twitter-login.component';
import { OpenAireLoginComponent } from "./openaire-login/openaire-login.component";
import { ConfigurableLoginComponent } from "./configurable-login/configurable-login.component";
const routes: Routes = [
{ path: '', component: LoginComponent },
@ -16,7 +17,8 @@ const routes: Routes = [
{ path: 'external/b2access', component: B2AccessLoginComponent },
{ path: 'confirmation/:token', component: EmailConfirmation },
{ path: 'confirmation', component: EmailConfirmation },
{ path: 'openaire', component: OpenAireLoginComponent}
{ path: 'openaire', component: OpenAireLoginComponent},
{ path: 'configurable/:id', component: ConfigurableLoginComponent}
];
@NgModule({

View File

@ -0,0 +1,15 @@
import { Injectable } from "@angular/core";
import { BaseService } from "../../../../core/common/base/base.service";
import { ConfigurableProvider } from "../../../../core/model/configurable-provider/configurableProvider";
@Injectable()
export class ConfigurableProvidersService extends BaseService {
public providers: ConfigurableProvider[];
constructor(
) {
super();
}
}