1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.frontend.filter;
20
21 import java.io.IOException;
22 import java.net.URISyntaxException;
23 import java.util.regex.Pattern;
24
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
27 import org.mycore.datamodel.ifs.MCRFileNodeServlet;
28 import org.mycore.frontend.MCRFrontendUtil;
29 import org.mycore.frontend.support.MCRSecureTokenV2;
30
31 import jakarta.servlet.Filter;
32 import jakarta.servlet.FilterChain;
33 import jakarta.servlet.FilterConfig;
34 import jakarta.servlet.ServletException;
35 import jakarta.servlet.ServletRequest;
36 import jakarta.servlet.ServletResponse;
37 import jakarta.servlet.http.HttpServletRequest;
38 import jakarta.servlet.http.HttpServletResponse;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class MCRSecureTokenV2Filter implements Filter {
59
60 private static final Logger LOGGER = LogManager.getLogger();
61
62 private boolean filterEnabled = true;
63
64 private String hashParameter;
65
66 private String sharedSecret;
67
68
69
70
71 @Override
72 public void init(FilterConfig filterConfig) throws ServletException {
73 filterEnabled = MCRSecureTokenV2FilterConfig.isFilterEnabled();
74 hashParameter = MCRSecureTokenV2FilterConfig.getHashParameterName();
75 sharedSecret = MCRSecureTokenV2FilterConfig.getSharedSecret();
76 }
77
78 @Override
79 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
80 throws IOException, ServletException {
81 if (filterEnabled) {
82 HttpServletRequest httpServletRequest = (HttpServletRequest) request;
83 String pathInfo = httpServletRequest.getPathInfo();
84 if (pathInfo != null && MCRSecureTokenV2FilterConfig.requireHash(pathInfo)) {
85 if (!validateSecureToken(httpServletRequest)) {
86 ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
87 LOGGER.warn("Access to {} forbidden by secure token check.", pathInfo);
88 return;
89 }
90 }
91 }
92 chain.doFilter(request, response);
93 }
94
95 private boolean validateSecureToken(HttpServletRequest httpServletRequest) throws ServletException {
96 String queryString = httpServletRequest.getQueryString();
97 if (queryString == null) {
98 LOGGER.warn("Request contains no parameters {}.", httpServletRequest.getRequestURL());
99 }
100 String hashValue = httpServletRequest.getParameter(hashParameter);
101 if (hashValue == null) {
102 LOGGER.warn("Could not find parameter '{}' in request {}.", hashParameter,
103 httpServletRequest.getRequestURL().append('?').append(queryString));
104 return false;
105 }
106 String[] origParams = Pattern.compile("&").split(queryString);
107 String[] stripParams = new String[origParams.length - 1];
108 for (int i = origParams.length - 1; i > -1; i--) {
109 if (origParams[i].startsWith(hashParameter + "=")) {
110 removeElement(origParams, stripParams, i);
111 }
112 }
113 MCRSecureTokenV2 token = new MCRSecureTokenV2(httpServletRequest.getPathInfo().substring(1),
114 MCRFrontendUtil.getRemoteAddr(httpServletRequest), sharedSecret, stripParams);
115 try {
116 LOGGER.info(token.toURI(MCRFrontendUtil.getBaseURL() + "servlets/MCRFileNodeServlet/", hashParameter));
117 } catch (URISyntaxException e) {
118 throw new ServletException(e);
119 }
120 return hashValue.equals(token.getHash());
121 }
122
123 private static void removeElement(String[] src, String[] dest, int i) {
124 if (i == 0) {
125 return;
126 }
127 System.arraycopy(src, 0, dest, 0, i - 1);
128 if (i < src.length - 1) {
129 System.arraycopy(src, i + 1, dest, i, src.length - 1 - i);
130 }
131 }
132
133 @Override
134 public void destroy() {
135 }
136
137 }