From 1db3fbee859ef3e2671c6099d1ab2db0333bdf59 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Tue, 25 May 2021 08:39:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebdavTeambitionApplication.java | 1 + .../config/EmbeddedTomcatConfig.java | 73 +++++++++++++++++++ .../webdavteambition/filter/ErrorFilter.java | 32 +++++++- .../store/AliYunDriverFileSystemStore.java | 25 +++++-- .../java/net/sf/webdav/WebDavServletBean.java | 27 ++++++- src/main/resources/application.properties | 4 +- 6 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java diff --git a/src/main/java/com/github/zxbu/webdavteambition/WebdavTeambitionApplication.java b/src/main/java/com/github/zxbu/webdavteambition/WebdavTeambitionApplication.java index 758ccee..0f8a0cd 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/WebdavTeambitionApplication.java +++ b/src/main/java/com/github/zxbu/webdavteambition/WebdavTeambitionApplication.java @@ -40,4 +40,5 @@ public class WebdavTeambitionApplication { return filterRegistrationBean; } + } diff --git a/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java b/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java new file mode 100644 index 0000000..634c419 --- /dev/null +++ b/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java @@ -0,0 +1,73 @@ +package com.github.zxbu.webdavteambition.config; + +import org.apache.catalina.authenticator.DigestAuthenticator; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.realm.GenericPrincipal; +import org.apache.catalina.realm.MessageDigestCredentialHandler; +import org.apache.catalina.realm.RealmBase; +import org.apache.tomcat.util.descriptor.web.SecurityCollection; +import org.apache.tomcat.util.descriptor.web.SecurityConstraint; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; + +import java.security.Principal; +import java.util.Collections; + +@Component +public class EmbeddedTomcatConfig implements WebServerFactoryCustomizer, Ordered { + + @Override + public void customize(ConfigurableServletWebServerFactory factory) { + + TomcatServletWebServerFactory tomcatServletWebServerFactory = (TomcatServletWebServerFactory) factory; + + tomcatServletWebServerFactory.addContextCustomizers(context -> { + + RealmBase realm = new RealmBase() { + @Override + protected String getPassword(String username) { + return "12345"; + } + + @Override + protected Principal getPrincipal(String username) { + return new GenericPrincipal(username, "12345", Collections.singletonList("*")); + } + }; + + MessageDigestCredentialHandler credentialHandler = new MessageDigestCredentialHandler(); +// try { +// credentialHandler.setAlgorithm("md5"); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } + realm.setCredentialHandler(credentialHandler); + + context.setRealm(realm); + DigestAuthenticator valve = new DigestAuthenticator(); + SecurityConstraint securityConstraint = new SecurityConstraint(); + securityConstraint.setAuthConstraint(true); + securityConstraint.addAuthRole("*"); +// securityConstraint.setUserConstraint("CONFIDENTIAL"); + SecurityCollection collection = new SecurityCollection(); + collection.addPattern("/*"); + securityConstraint.addCollection(collection); + + context.addConstraint(securityConstraint); + + StandardContext standardContext = (StandardContext) context; + + + context.getPipeline().addValve(valve); + }); + + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/zxbu/webdavteambition/filter/ErrorFilter.java b/src/main/java/com/github/zxbu/webdavteambition/filter/ErrorFilter.java index 9ed6132..ef9259a 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/filter/ErrorFilter.java +++ b/src/main/java/com/github/zxbu/webdavteambition/filter/ErrorFilter.java @@ -1,5 +1,8 @@ package com.github.zxbu.webdavteambition.filter; +import net.sf.webdav.WebdavStatus; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import org.springframework.core.io.ClassPathResource; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; @@ -9,10 +12,24 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; public class ErrorFilter extends OncePerRequestFilter { + private static final String errorPage = readErrorPage(); + private static String readErrorPage() { + try { + ClassPathResource classPathResource = new ClassPathResource("error.xml"); + InputStream inputStream = classPathResource.getInputStream(); + byte[] buffer = new byte[(int) classPathResource.contentLength()]; + IOUtils.readFully(inputStream, buffer); + return new String(buffer, StandardCharsets.UTF_8); + } catch (IOException e) { + return ""; + } + } @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { @@ -21,10 +38,19 @@ public class ErrorFilter extends OncePerRequestFilter { try { filterChain.doFilter(httpServletRequest, wrapperResponse); if (wrapperResponse.hasErrorToSend()) { - httpServletResponse.setStatus(wrapperResponse.getStatus()); - if (wrapperResponse.getMessage() != null) { - httpServletResponse.getWriter().write(wrapperResponse.getMessage()); + int status = wrapperResponse.getStatus(); + if (status == 401) { +// httpServletResponse.addHeader("WWW-Authenticate", "Digest realm=\"iptel.org\", qop=\"auth,auth-int\",\n" + +// "nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"\", algorithm=MD5"); +// + } + httpServletResponse.setStatus(status); + String message = wrapperResponse.getMessage(); + if (message == null) { + message = WebdavStatus.getStatusText(status); } + String errorXml = errorPage.replace("{{code}}", status + "").replace("{{message}}", message); + httpServletResponse.getWriter().write(errorXml); } httpServletResponse.flushBuffer(); } catch (Throwable t) { diff --git a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java index 6d8c113..70379a3 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java +++ b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java @@ -3,10 +3,8 @@ package com.github.zxbu.webdavteambition.store; import com.github.zxbu.webdavteambition.model.FileType; import com.github.zxbu.webdavteambition.model.PathInfo; import com.github.zxbu.webdavteambition.model.result.TFile; -import net.sf.webdav.ITransaction; -import net.sf.webdav.IWebdavStore; -import net.sf.webdav.StoredObject; -import net.sf.webdav.Transaction; +import net.sf.webdav.*; +import net.sf.webdav.exceptions.UnauthenticatedException; import net.sf.webdav.exceptions.WebdavException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +15,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.security.Principal; +import java.util.Enumeration; import java.util.Set; public class AliYunDriverFileSystemStore implements IWebdavStore { @@ -43,6 +42,17 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public ITransaction begin(Principal principal, HttpServletRequest req, HttpServletResponse resp) { LOGGER.debug("begin"); + Enumeration headerNames = req.getHeaderNames(); + System.out.println(req.getMethod() + " " + req.getRequestURI()); + System.out.println("principal:" + principal); + while (headerNames.hasMoreElements()) { + String s = headerNames.nextElement(); + System.out.println(s + ":" + req.getHeader(s)); + } + + + System.out.println("-----------------------"); + System.out.println(); aliYunDriverClientService.clearCache(); return new Transaction(principal, req, resp); @@ -51,9 +61,10 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public void checkAuthentication(ITransaction transaction) { LOGGER.debug("checkAuthentication"); -// if (transaction.getPrincipal() == null) { -// throw new UnauthenticatedException(WebdavStatus.SC_UNAUTHORIZED); -// } + HttpServletRequest req = transaction.getRequest(); + if (transaction.getPrincipal() == null) { + throw new UnauthenticatedException(WebdavStatus.SC_UNAUTHORIZED); + } } @Override diff --git a/src/main/java/net/sf/webdav/WebDavServletBean.java b/src/main/java/net/sf/webdav/WebDavServletBean.java index dacfaaa..d1f32ea 100644 --- a/src/main/java/net/sf/webdav/WebDavServletBean.java +++ b/src/main/java/net/sf/webdav/WebDavServletBean.java @@ -109,6 +109,10 @@ public class WebDavServletBean extends HttpServlet { if (LOG.isTraceEnabled()) debugRequest(methodName, req); + if (returnError(req, resp)) { + return; + } + try { Principal userPrincipal = getUserPrincipal(req); transaction = _store.begin(userPrincipal, req, resp); @@ -171,15 +175,32 @@ public class WebDavServletBean extends HttpServlet { } /** - * Method that permit to customize the way + * Method that permit to customize the way * user information are extracted from the request, default use JAAS + * * @param req * @return */ protected Principal getUserPrincipal(HttpServletRequest req) { - return req.getUserPrincipal(); + return req.getUserPrincipal(); } - + + private boolean returnError(HttpServletRequest req, HttpServletResponse resp) throws IOException { + if (req.getRequestURI().equals("/error")) { + Object codeObject = req.getAttribute("javax.servlet.error.status_code"); + if (codeObject != null) { + int code = Integer.parseInt(codeObject.toString()); + if (code > 400) { + resp.setStatus(code); + resp.flushBuffer(); + return true; + } + } + } + return false; + } + + private void debugRequest(String methodName, HttpServletRequest req) { LOG.trace("-----------"); LOG.trace("WebdavServlet\n request: methodName = " + methodName); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cf6f6e3..b7eeb0d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,3 @@ -#logging.level.net.sf.webdav=trace +logging.level.net.sf.webdav=trace logging.file.path=/var/log/ -logging.file.name=webdav.log \ No newline at end of file +logging.file.name=webdav.log From 897a279e4f6da72ca96c6bd592c602fc6823d345 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Tue, 25 May 2021 08:40:42 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/sf/webdav/WebDavServletBean.java | 1 - src/main/resources/error.xml | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/error.xml diff --git a/src/main/java/net/sf/webdav/WebDavServletBean.java b/src/main/java/net/sf/webdav/WebDavServletBean.java index d1f32ea..a92ed75 100644 --- a/src/main/java/net/sf/webdav/WebDavServletBean.java +++ b/src/main/java/net/sf/webdav/WebDavServletBean.java @@ -177,7 +177,6 @@ public class WebDavServletBean extends HttpServlet { /** * Method that permit to customize the way * user information are extracted from the request, default use JAAS - * * @param req * @return */ diff --git a/src/main/resources/error.xml b/src/main/resources/error.xml new file mode 100644 index 0000000..1e53462 --- /dev/null +++ b/src/main/resources/error.xml @@ -0,0 +1,9 @@ + + + + + + HTTP/1.1 {{code}} {{message}} + + + \ No newline at end of file From 53ccfd587bed785b0b4c7f78b967f7f79dd94798 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Tue, 25 May 2021 10:39:58 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=94=AF=E6=8C=81=20=E8=B4=A6=E6=88=B7?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../config/AliYunDriveProperties.java | 39 +++++++++++++++++++ .../config/EmbeddedTomcatConfig.java | 33 +++++++--------- .../store/AliYunDriverFileSystemStore.java | 13 ------- src/main/resources/application.properties | 6 ++- 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 4bd5228..8702caf 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.zxbu webdav-aliyundriver - 2.1.0 + 2.2.0 webdav Demo project for Spring Boot diff --git a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriveProperties.java b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriveProperties.java index 311e0bd..410a1a8 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriveProperties.java +++ b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriveProperties.java @@ -10,6 +10,7 @@ public class AliYunDriveProperties { private String workDir = "/etc/aliyun-driver/"; private String agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"; private String driveId; + private Auth auth; public String getUrl() { return url; @@ -58,4 +59,42 @@ public class AliYunDriveProperties { public void setDriveId(String driveId) { this.driveId = driveId; } + + public Auth getAuth() { + return auth; + } + + public void setAuth(Auth auth) { + this.auth = auth; + } + + public static class Auth { + private Boolean enable = true; + private String userName; + private String password; + + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + } } diff --git a/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java b/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java index 634c419..56adee2 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java +++ b/src/main/java/com/github/zxbu/webdavteambition/config/EmbeddedTomcatConfig.java @@ -1,12 +1,13 @@ package com.github.zxbu.webdavteambition.config; import org.apache.catalina.authenticator.DigestAuthenticator; -import org.apache.catalina.core.StandardContext; import org.apache.catalina.realm.GenericPrincipal; import org.apache.catalina.realm.MessageDigestCredentialHandler; import org.apache.catalina.realm.RealmBase; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; @@ -17,8 +18,12 @@ import java.security.Principal; import java.util.Collections; @Component +@ConditionalOnProperty(prefix = "aliyundrive.auth", name = "enable", matchIfMissing = true) public class EmbeddedTomcatConfig implements WebServerFactoryCustomizer, Ordered { + @Autowired + private AliYunDriveProperties aliYunDriveProperties; + @Override public void customize(ConfigurableServletWebServerFactory factory) { @@ -29,39 +34,31 @@ public class EmbeddedTomcatConfig implements WebServerFactoryCustomizer headerNames = req.getHeaderNames(); - System.out.println(req.getMethod() + " " + req.getRequestURI()); - System.out.println("principal:" + principal); - while (headerNames.hasMoreElements()) { - String s = headerNames.nextElement(); - System.out.println(s + ":" + req.getHeader(s)); - } - - - System.out.println("-----------------------"); - System.out.println(); - aliYunDriverClientService.clearCache(); return new Transaction(principal, req, resp); } @@ -61,7 +49,6 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public void checkAuthentication(ITransaction transaction) { LOGGER.debug("checkAuthentication"); - HttpServletRequest req = transaction.getRequest(); if (transaction.getPrincipal() == null) { throw new UnauthenticatedException(WebdavStatus.SC_UNAUTHORIZED); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b7eeb0d..ccfd3fe 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,7 @@ -logging.level.net.sf.webdav=trace +#logging.level.net.sf.webdav=trace logging.file.path=/var/log/ logging.file.name=webdav.log + +aliyundrive.auth.enable=true +aliyundrive.auth.user-name=admin +aliyundrive.auth.password=admin