Skip to content

Commit c3105c6

Browse files
Merge remote-tracking branch 'origin/maven/fixes/9.1' into maven/release/9.1
2 parents 6c6075d + 048b9b1 commit c3105c6

File tree

15 files changed

+347
-22
lines changed

15 files changed

+347
-22
lines changed

Backend/alfresco/common/src/main/java/org/edu_sharing/repository/client/tools/CCConstants.java

+3
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,9 @@ public static String getValidGlobalName(String value){
22782278
public static final String ELASTICSEARCH_SYNONYMSET_PREFIX = "es-synonym-set";
22792279
public static final String ELASTICSEARCH_ANALYZER_PREFIX = "synonyms";
22802280

2281+
public static final String EDU_PASSWORD_KEYSTORE_NAME = "edupasswords";
2282+
public static final String EDU_PASSWORD_USERNAMEHASH = "usernamehash";
2283+
22812284
/**
22822285
* Methos that set all the Properties for ProfileSettings
22832286
* @return (List) list of all properties we want to be in ProfileSettings

Backend/alfresco/module/src/main/amp/config/log4j2.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ appender.console.type=Console
88
appender.console.name=ConsoleAppender
99
appender.console.layout.type=PatternLayout
1010
# use log4j NDC to replace %x with tenant domain / username
11-
appender.console.layout.pattern=%d{ISO8601} %X %-5p [%c{3}] [%t] %replace{%m}{[\r\n]+}{}%n
11+
# appender.console.layout.pattern=%d{ISO8601} { %notEmpty{%X{SpanId} }%notEmpty{%X{TraceId} }%notEmpty{%X{EduVersion} }%notEmpty{%X{LogEventDate}}} %-5p [%c{3}] [%t] %replace{%m}{[\r\n]+}{}%n
12+
appender.console.layout.pattern=%d{ISO8601} {%notEmpty{%X{SpanId} %X{TraceId}}} %-5p [%c{3}] [%t] %replace{%m}{[\r\n]+}{}%n
13+
1214

1315
###### Log level overrides #######
1416
# Commented-in loggers will be exposed as JMX MBeans (refer to org.alfresco.repo.admin.Log4JHierarchyInit)

Backend/alfresco/module/src/main/java/org/edu_sharing/repository/server/tools/ApplicationInfo.java

+10
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ public class ApplicationInfo implements Comparable<ApplicationInfo>, Serializabl
115115
public static final String KEY_PRIVATE_KEY = "private_key";
116116

117117
public static final String KEY_CERTIFICATE = "certificate";
118+
119+
public static final String KEY_KEYSTORE_PW = "keystore_pw";
118120

119121
public static final String KEY_MESSAGE_OFFSET_MILLISECONDS = "message_offset_ms";
120122
public static final String KEY_MESSAGE_SEND_OFFSET_MILLISECONDS = "message_send_offset_ms";
@@ -427,6 +429,8 @@ public class ApplicationInfo implements Comparable<ApplicationInfo>, Serializabl
427429
private String cookieAttributes;
428430
private Map<CacheKey, Serializable> cache = new HashMap<>();
429431

432+
private String keyStorePassword;
433+
430434
public ApplicationInfo(String _appFile) throws Exception{
431435
if(_appFile == null) throw new Exception("Application Filename was null!");
432436
appFileName = _appFile;
@@ -564,6 +568,8 @@ public ApplicationInfo(String _appFile) throws Exception{
564568
validatorRegexCMName = cmNameRegex;
565569
}
566570

571+
keyStorePassword = properties.getProperty(KEY_KEYSTORE_PW);
572+
567573
ltiClientId = properties.getProperty(KEY_LTI_CLIENT_ID);
568574
ltiIss = properties.getProperty(KEY_LTI_ISS);
569575
ltiDeploymentId = properties.getProperty(KEY_LTI_DEPLOYMENT_ID);
@@ -1136,4 +1142,8 @@ public boolean isLtiScopeUsername() {
11361142
public String getCertificate() {
11371143
return certificate;
11381144
}
1145+
1146+
public String getKeyStorePassword() {
1147+
return keyStorePassword;
1148+
}
11391149
}

Backend/services/core/src/main/java/org/alfresco/repo/webdav/auth/LDAPAuthenticationFilter.java

+11-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.edu_sharing.alfresco.lightbend.LightbendConfigLoader;
2525
import org.edu_sharing.alfrescocontext.gate.AlfAppContextGate;
2626
import org.edu_sharing.repository.client.tools.CCConstants;
27+
import org.edu_sharing.repository.server.tools.security.HMac;
2728
import org.springframework.context.ApplicationContext;
2829

2930
import javax.naming.CommunicationException;
@@ -40,9 +41,6 @@
4041
import java.util.*;
4142

4243

43-
/**
44-
* Servlet Filter implementation class CockpitAuthenticationFilter
45-
*/
4644
/**
4745
* Servlet Filter implementation class CockpitAuthenticationFilter
4846
*/
@@ -108,6 +106,8 @@ public class LDAPAuthenticationFilter implements Filter, DependencyInjectedFilte
108106
private String ldapUidProp = null;
109107
private String ldapUrl = null;
110108

109+
HMac hMac = null;
110+
111111

112112
/**
113113
* edu-sharing fix from 4.2.f
@@ -188,6 +188,7 @@ public void init(FilterConfig config) throws ServletException
188188
env.put(Context.SECURITY_PRINCIPAL, eduConfig.getString(LDAPAuthenticationFilter.INIT_LDAP_SEC_USER));
189189
env.put(Context.SECURITY_CREDENTIALS, eduConfig.getString(LDAPAuthenticationFilter.INIT_LDAP_SEC_PWD));
190190

191+
hMac = HMac.getInstance();
191192
}
192193

193194
/**
@@ -341,7 +342,7 @@ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain
341342

342343
// Authenticate the user
343344
try{
344-
logger.info("webdav ldap authentication: starting. loginName:####");
345+
logger.info("webdav ldap authentication: starting. loginName:"+hMac.calculateHmac(username));
345346
user = searchForUser(username,password);
346347
}catch(CommunicationException e){
347348
logger.error(e.getMessage() +" Will create new InitialDirContext and retry.");
@@ -570,7 +571,7 @@ WebDAVUser searchForUser(String loginName, String password) throws Communication
570571
dn = r.getNameInNamespace();
571572

572573
}else{
573-
throw new AuthenticationException("webdav ldap authentication: user not found in directory. loginName:###");
574+
throw new AuthenticationException("webdav ldap authentication: user not found in directory. loginName:" + hMac.calculateHmac(loginName));
574575
}
575576
rs.close();
576577

@@ -591,7 +592,7 @@ WebDAVUser searchForUser(String loginName, String password) throws Communication
591592
return true;
592593
});
593594
if(!allowed){
594-
throw new AuthenticationException("webdav ldap authentication: USER_BLOCKED. loginName: ### / userName: ###");
595+
throw new AuthenticationException("webdav ldap authentication: USER_BLOCKED. loginName:" + hMac.calculateHmac(loginName) + " / userName:" + hMac.calculateHmac(username) );
595596
}
596597
}
597598

@@ -625,12 +626,12 @@ WebDAVUser searchForUser(String loginName, String password) throws Communication
625626
} catch (AuthenticationException ex) {
626627
// Do nothing, user object will be null
627628
if(ex.getMessage() != null && ex.getMessage().contains("Invalid Credentials")){
628-
logger.warn("webdav ldap authentication: failed with Invalid Credentials. loginName: ### / userName: ###");
629+
logger.error("webdav ldap authentication: failed with Invalid Credentials. loginName:" + hMac.calculateHmac(loginName) + " / userName:" + hMac.calculateHmac(username));
629630
}
630631
if (ex.getMessage() != null && ex.getMessage().contains("DN with no password")) {
631-
logger.warn("webdav ldap authentication: no password provided. loginName: ### / userName: ###");
632+
logger.error("webdav ldap authentication: no password provided. loginName:" + hMac.calculateHmac(loginName) + " / userName:" + hMac.calculateHmac(username));
632633
}else {
633-
logger.warn(ex.getMsgId());
634+
logger.error(ex.getMsgId());
634635
if (logger.isDebugEnabled()) {
635636
logger.error(ex.getMessage(), ex);
636637
}
@@ -669,7 +670,7 @@ private void authenticate(String ldapUserDn, String username, String password, S
669670
ApplicationContext context = AlfAppContextGate.getApplicationContext();
670671
AuthenticationComponent authComp = (AuthenticationComponent)context.getBean("authenticationComponent");
671672
authComp.setCurrentUser(username);
672-
logger.info("webdav ldap authentication: sucessfull. loginName: ### / userName: ###");
673+
logger.info("webdav ldap authentication: sucessfull. loginName:" + hMac.calculateHmac(loginName) +" / userName:" + hMac.calculateHmac(username));
673674
return;
674675
}catch(javax.naming.AuthenticationException e){
675676
logger.debug(e.getMessage(), e);

Backend/services/core/src/main/java/org/edu_sharing/repository/server/authentication/ContextManagementFilter.java

+43-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import java.io.IOException;
44
import java.io.Serializable;
5+
import java.util.Date;
56
import java.util.Map;
67

78
import jakarta.servlet.*;
89
import jakarta.servlet.http.HttpServletRequest;
910
import jakarta.servlet.http.HttpServletResponse;
11+
import java.text.SimpleDateFormat;
1012

1113
import org.alfresco.repo.security.authentication.AuthenticationComponent;
1214
import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -24,6 +26,7 @@
2426
import org.edu_sharing.repository.client.tools.CCConstants;
2527
import org.edu_sharing.repository.server.AuthenticationToolAPI;
2628
import org.edu_sharing.repository.server.tools.ApplicationInfoList;
29+
import org.edu_sharing.repository.server.tools.security.HMac;
2730
import org.edu_sharing.repository.server.tools.security.SignatureVerifier;
2831
import org.edu_sharing.restservices.NodeDao;
2932
import org.edu_sharing.restservices.RepositoryDao;
@@ -35,10 +38,13 @@
3538
import org.edu_sharing.service.usage.Usage;
3639
import org.edu_sharing.service.usage.Usage2Service;
3740
import org.edu_sharing.service.usage.Usage2Exception;
41+
import org.edu_sharing.spring.ApplicationContextFactory;
3842
import org.edu_sharing.webservices.util.AuthenticationUtils;
3943

4044
import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
4145
import org.springframework.context.ApplicationContext;
46+
import org.apache.logging.log4j.ThreadContext;
47+
import org.edu_sharing.service.version.VersionService;
4248

4349

4450
public class ContextManagementFilter implements jakarta.servlet.Filter {
@@ -54,13 +60,22 @@ public class ContextManagementFilter implements jakarta.servlet.Filter {
5460
AuthenticationService authservice = serviceRegistry.getAuthenticationService();
5561
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
5662

63+
HMac hMac = null;
64+
65+
SimpleDateFormat logEventDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
66+
67+
private VersionService versionService;
68+
5769
@Override
5870
public void destroy() {
5971
}
6072

6173
@Override
6274
public void init(FilterConfig config) throws ServletException {
6375
this.context=config.getServletContext();
76+
hMac = HMac.getInstance();
77+
78+
versionService = ApplicationContextFactory.getApplicationContext().getBean(VersionService.class);
6479
}
6580

6681
@Override
@@ -76,12 +91,37 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
7691
ScopeAuthenticationServiceFactory.getScopeAuthenticationService().setScopeForCurrentThread();
7792

7893
try{
94+
String user = (String) ((HttpServletRequest) req).getSession().getAttribute(CCConstants.AUTH_USERNAME);
7995
// Run as System because there is yet no session opened
8096
Map<String, Serializable> info = AuthenticationUtil.runAsSystem(() ->
8197
AuthorityServiceFactory.getLocalService().getUserInfo(
82-
(String) ((HttpServletRequest) req).getSession().getAttribute(CCConstants.AUTH_USERNAME))
98+
user)
8399
);
84100
QueryUtils.setUserInfo(info);
101+
102+
String remoteAdress = ((HttpServletRequest) req).getHeader("x-forwarded-for");
103+
if(remoteAdress == null){
104+
remoteAdress = req.getRemoteAddr();
105+
}
106+
if(remoteAdress != null) {
107+
ThreadContext.put("RemoteAddr", remoteAdress);
108+
}
109+
110+
String ua = ((HttpServletRequest) req).getHeader("user-agent");
111+
if(ua != null){
112+
ThreadContext.put("UserAgent",ua);
113+
}
114+
115+
if(user != null){
116+
String hmac = hMac.calculateHmac(user.trim());
117+
ThreadContext.put("UserPlain",user);
118+
ThreadContext.put("User",hmac);
119+
}
120+
121+
ThreadContext.put("Url",((HttpServletRequest)req).getRequestURL().toString());
122+
ThreadContext.put("EduVersion", versionService.getVersionNoException(VersionService.Type.REPOSITORY));
123+
ThreadContext.put("LogEventDate",logEventDateFormat.format(new Date()));
124+
85125
}catch(Exception e){
86126
logger.info("Could not set user info: "+e.getMessage());
87127
}
@@ -146,6 +186,8 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
146186
//for soap api
147187
AuthenticationUtils.setAuthenticationDetails(null);
148188

189+
ThreadContext.clearAll();
190+
149191
}
150192

151193
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.edu_sharing.repository.server.tools.security;
2+
3+
4+
import org.apache.commons.codec.digest.HmacUtils;
5+
import org.apache.log4j.Logger;
6+
import org.edu_sharing.repository.client.tools.CCConstants;
7+
import org.edu_sharing.repository.server.tools.ApplicationInfoList;
8+
9+
10+
public class HMac {
11+
12+
public static final String ALG_SHA256 = "HmacSHA256";
13+
14+
15+
Logger logger = Logger.getLogger(HMac.class);
16+
17+
String sharedSecret;
18+
String algorithm;
19+
20+
21+
public HMac(String sharedSecret, String algorithm){
22+
this.sharedSecret = sharedSecret;
23+
this.algorithm = algorithm;
24+
}
25+
26+
public String calculateHmac(String data) {
27+
//had problems using HmacUtils as class member and reuse, sometimes got another hex for the same data
28+
// so reinit
29+
HmacUtils hmacUtils = new HmacUtils(algorithm,sharedSecret);
30+
return hmacUtils.hmacHex(data);
31+
}
32+
33+
public boolean checkHmac(String data, String hmacHex) {
34+
return calculateHmac(data).equals(hmacHex);
35+
}
36+
37+
public static HMac getInstance() {
38+
KeyStoreService keyStoreService = new KeyStoreService();
39+
40+
try {
41+
String hmacPassword = keyStoreService.readPasswordFromKeyStore(CCConstants.EDU_PASSWORD_KEYSTORE_NAME,
42+
ApplicationInfoList.getHomeRepository().getKeyStorePassword(),"",CCConstants.EDU_PASSWORD_USERNAMEHASH);
43+
return new HMac(hmacPassword,HMac.ALG_SHA256);
44+
} catch (Exception e) {
45+
throw new RuntimeException(e);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)