dnet-core/dnet-modular-ui/src/main/java/eu/dnetlib/functionality/modular/ui/users/SimpleSSOAuthorizationManag...

164 lines
4.6 KiB
Java

package eu.dnetlib.functionality.modular.ui.users;
import java.net.URLDecoder;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.google.gson.Gson;
public class SimpleSSOAuthorizationManager implements AuthorizationManager {
private static final Log log = LogFactory.getLog(SimpleSSOAuthorizationManager.class);
private Resource pubKeyFile = new ClassPathResource("/eu/dnetlib/functionality/modular/ui/users/pubkey.der");
private String pubKeyAlgo = "RSA";
private String signatureAlgo = "SHA1withRSA";
private PublicKey publicKey;
private AuthorizationDAO authorizationDAO;
private String defaultSuperAdmin;
@Override
public User obtainUserDetails(final HttpServletRequest request) {
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equalsIgnoreCase("rinfra-user")) {
try {
return processCookie(cookie.getValue());
} catch (Exception e) {
log.error("Error processing cookie: " + cookie.getValue(), e);
return null;
}
}
}
}
return null;
}
private User processCookie(final String s) throws Exception {
if (s == null || s.isEmpty()) {
return null;
}
final Gson gson = new Gson();
final Map<?,?> map = gson.fromJson(new String(Base64.decodeBase64(URLDecoder.decode(s.trim(), "UTF-8"))), Map.class);
final String message = (String) map.get("payload");
final String signature = (String) map.get("signature");
if (isValidMessage(message, signature)) {
final Map<?,?> userMap = gson.fromJson(message, Map.class);
if (userMap.containsKey("uid")) {
final String uid = (String) userMap.get("uid");
final User user = new User(uid);
user.setEmail((String) userMap.get("email"));
user.setFullname(userMap.containsKey("fullname") ? (String) userMap.get("fullname") : uid);
user.setPermissionLevels(authorizationDAO.getPermissionLevels(uid));
if (isDefaultSuperAdmin(uid)) {
user.getPermissionLevels().add(PermissionLevel.SUPER_ADMIN);
}
return user;
}
}
return null;
}
private boolean isDefaultSuperAdmin(final String uid) {
return (uid != null && !uid.isEmpty() && uid.equals(getDefaultSuperAdmin()));
}
protected boolean isValidMessage(final String message, final String signature) {
log.info("checking message " + message + " with sig " + signature);
if (message == null || message.isEmpty() || signature == null || signature.isEmpty()) {
log.error("Null or empty values in message or signature");
return false;
}
try {
final Signature sg = Signature.getInstance(getSignatureAlgo());
sg.initVerify(getPublicKey());
sg.update(message.getBytes());
return sg.verify(Hex.decodeHex(signature.toCharArray()));
} catch(Exception e) {
log.error("Error verifyng signature", e);
return false;
}
}
public void init() throws Exception {
final byte[] keyBytes = IOUtils.toByteArray(getPubKeyFile().getInputStream());
final KeySpec spec = new X509EncodedKeySpec(keyBytes);
setPublicKey(KeyFactory.getInstance(getPubKeyAlgo()).generatePublic(spec));
}
public Resource getPubKeyFile() {
return pubKeyFile;
}
@Required
public void setPubKeyFile(Resource pubKeyFile) {
this.pubKeyFile = pubKeyFile;
}
public String getPubKeyAlgo() {
return pubKeyAlgo;
}
@Required
public void setPubKeyAlgo(String pubKeyAlgo) {
this.pubKeyAlgo = pubKeyAlgo;
}
public String getSignatureAlgo() {
return signatureAlgo;
}
@Required
public void setSignatureAlgo(String signatureAlgo) {
this.signatureAlgo = signatureAlgo;
}
public PublicKey getPublicKey() {
return publicKey;
}
public void setPublicKey(PublicKey publicKey) {
this.publicKey = publicKey;
}
public AuthorizationDAO getAuthorizationDAO() {
return authorizationDAO;
}
@Required
public void setAuthorizationDAO(AuthorizationDAO authorizationDAO) {
this.authorizationDAO = authorizationDAO;
}
public String getDefaultSuperAdmin() {
return defaultSuperAdmin;
}
@Required
public void setDefaultSuperAdmin(String defaultSuperAdmin) {
this.defaultSuperAdmin = defaultSuperAdmin;
}
}