Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge latest changes #55

Merged
merged 12 commits into from
Dec 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public class ResourceDiscoveryProperties {
private boolean salRegistrationEnabled = true;
private long salRegistrationTimeout = 60*1000;
private String registration_topic_name = "eu.nebulouscloud.exn.sal.node.create";

private String deregistration_topic_prefix = "eu.nebulouscloud.exn.sal.node.delete";

// Failed devices detection
private boolean automaticFailedDetection = true;
private long suspectDeviceThreshold = 5; // in minutes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.nebulous.resource.discovery;

import eu.nebulous.resource.discovery.registration.controller.RegistrationRequestController;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand All @@ -15,6 +16,7 @@
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
Expand All @@ -26,6 +28,7 @@

import java.security.SecureRandom;
import java.util.Collections;
import java.util.HashMap;

import static org.springframework.security.config.Customizer.withDefaults;

Expand All @@ -37,6 +40,8 @@
public class SecurityConfig {
private final static String USERNAME_REQUEST_HEADER = "X-SSO-USER";
private final static String USERNAME_REQUEST_PARAM = "ssoUser";
private final static String NONCE_REQUEST_PARAM = "nonce";
private final static String APPID_REQUEST_PARAM = "appId";
private final static String API_KEY_REQUEST_HEADER = "X-API-KEY";
private final static String API_KEY_REQUEST_PARAM = "apiKey";

Expand All @@ -54,6 +59,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
"/discovery/**", "/*.html").authenticated())
.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll())
.addFilterAfter(apiKeyAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(nonceAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));

Expand Down Expand Up @@ -100,6 +106,13 @@ public boolean matches(CharSequence rawPassword, String encodedPassword) {

public Filter apiKeyAuthenticationFilter() {
return (servletRequest, servletResponse, filterChain) -> {

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth!=null && auth.isAuthenticated()) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}

if (properties.isApiKeyAuthenticationEnabled() && StringUtils.isNotBlank(properties.getApiKeyValue())) {
if (servletRequest instanceof HttpServletRequest request && servletResponse instanceof HttpServletResponse) {

Expand Down Expand Up @@ -149,4 +162,65 @@ public Filter apiKeyAuthenticationFilter() {
filterChain.doFilter(servletRequest, servletResponse);
};
}

public Filter nonceAuthenticationFilter(){
return (servletRequest, servletResponse, filterChain) -> {
try {
HttpServletRequest request = ((HttpServletRequest )servletRequest);
// HttpSession session = request.getSession(false);
//
// if(session!=null){
// filterChain.doFilter(servletRequest, servletResponse);
// return;
// }
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth!=null && auth.isAuthenticated()) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
String queryString = request.getQueryString();

if (queryString == null) {
log.warn( requestURL.toString());
} else {
log.warn(requestURL.append('?').append(queryString).toString());
}
log.warn(servletRequest.toString());

String nonce = servletRequest.getParameter(NONCE_REQUEST_PARAM);
String appId = servletRequest.getParameter(APPID_REQUEST_PARAM);

String username =null;
HashMap<String, String> map = new HashMap<>();
map.put(NONCE_REQUEST_PARAM, nonce);
map.put(APPID_REQUEST_PARAM, appId);
username = RegistrationRequestController.getNonceUsername(map);
// if ((nonce != null && appId != null) && (!nonce.isEmpty())) {
// HashMap<String, String> map = new HashMap<>();
// map.put(NONCE_REQUEST_PARAM, nonce);
// map.put(APPID_REQUEST_PARAM, appId);
// username = RegistrationRequestController.getNonceUsername(map);
// }

if (username != null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(username, nonce,
Collections.singletonList(new SimpleGrantedAuthority(SSO_USER_ROLE)));
// store completed authentication in security context
SecurityContextHolder.getContext().setAuthentication(authentication);
log.debug("User was authenticated using a nonce token");
}

} catch (Exception e) {
log.error("nonceAuthenticationFilter: EXCEPTION: ", e);
}

// continue down the chain
filterChain.doFilter(servletRequest, servletResponse);

};
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ public BrokerPublisher(String topic, String broker_ip, int broker_port, String b
throw new RuntimeException(e);
}
}
active_connector.stop();
try {
active_connector.stop(); //TODO reassure expected stop() functionality is working here when this is necessary
}catch (Exception e){
e.printStackTrace();
}
}

}
Expand Down Expand Up @@ -104,23 +108,27 @@ public BrokerPublisher(String topic, String broker_ip, int broker_port, String b

//TODO The methods below assume that the only content to be sent is json-like
public void publish (String json_string_content, Collection<String> application_names){

for (String application_name : application_names) {
JSONParser parser = new JSONParser();
JSONObject json_object = new JSONObject();
try {
json_object = (JSONObject) parser.parse(json_string_content);
} catch (ParseException p) {
log.warn( "publish: Could not parse the string content to be published to the broker as json, which is the following: "+json_string_content);
}
if (!is_publisher_null()) {
private_publisher_instance.send(json_object);
log.info("Sent new message\n"+json_object.toJSONString());
} else {
log.error( "Could not send message to AMQP broker, as the publisher instance is null");
}
publish(json_string_content);
}
}

public void publish (String json_string_content){
JSONParser parser = new JSONParser();
JSONObject json_object = new JSONObject();
try {
json_object = (JSONObject) parser.parse(json_string_content);
} catch (ParseException p) {
log.warn( "publish: Could not parse the string content to be published to the broker as json, which is the following: "+json_string_content);
}
if (!is_publisher_null()) {
private_publisher_instance.send(json_object);
log.info("Sent new message\n"+json_object.toJSONString());
} else {
log.error( "Could not send message to AMQP broker, as the publisher instance is null");
}
}

public boolean is_publisher_null(){
return (private_publisher_instance == null);
}
Expand Down
Loading