From 0653e8d3190a12e3beb06812600a6a82482737c5 Mon Sep 17 00:00:00 2001
From: 李宇 <986321569@qq.com>
Date: 星期四, 14 一月 2021 15:23:00 +0800
Subject: [PATCH] 修改shiro1.6引起的登录问题

---
 src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java |  186 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 186 insertions(+), 0 deletions(-)

diff --git a/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java b/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java
new file mode 100644
index 0000000..48fcb2e
--- /dev/null
+++ b/src/main/java/org/apache/shiro/web/filter/InvalidRequestFilter.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.shiro.web.filter;
+
+import org.apache.shiro.web.util.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A request filter that blocks malicious requests. Invalid request will respond with a 400 response code.
+ *
+
+
+ * This filter checks and blocks the request if the following characters are found in the request URI:
+ *
+
+
+ *
+ Semicolon - can be disabled by setting {@code blockSemicolon = false}
+
+ *
+ Backslash - can be disabled by setting {@code blockBackslash = false}
+
+ *
+ Non-ASCII characters - can be disabled by setting {@code blockNonAscii = false}, the ability to disable this check will be removed in future version.
+
+ *
+
+
+ *
+ * @see  class was inspired by Spring Security StrictHttpFirewall
+ * @since 1.6
+ */
+public class InvalidRequestFilter extends AccessControlFilter {
+
+    private static final List<String>  SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
+
+    private static final List<String>  BACKSLASH = Collections.unmodifiableList(Arrays.asList("\\", "%5c", "%5C"));
+
+    private boolean blockSemicolon = true;
+
+    private boolean blockBackslash = true;
+
+    private boolean blockNonAscii = true;
+
+    @Override
+    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
+        String uri = WebUtils.toHttp(request).getRequestURI();
+        return !containsSemicolon(request,uri)
+                && !containsBackslash(uri)
+                && !containsNonAsciiCharacters(uri);
+    }
+
+    @Override
+    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
+        String uri = WebUtils.toHttp(request).getRequestURI();
+        WebUtils.toHttp(response).sendError(400, "Invalid request");
+        return false;
+    }
+
+    private String ctx=null;
+    private boolean containsSemicolon(ServletRequest request,String uri) {
+        if (isBlockSemicolon()) {
+            if(ctx == null) {
+                ctx = WebUtils.toHttp(request).getContextPath();
+            }
+            // 登录url拼接的jsessionId进行放行
+            if(uri.startsWith(ctx + this.getLoginUrl() + ";jsessionid=") ||
+                    uri.startsWith(ctx + this.getLoginUrl() + "%3bjsessionid=") ||
+                    uri.startsWith(ctx + this.getLoginUrl() + "%3Bjsessionid=") ||
+                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/mybootstrap.css.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/default.css.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/components.css.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery-plugins.js.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/jquery/jquery.js.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/core.js.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/extra.js.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/resources/images/logo1.png;jsessionid=")||
+                    uri.startsWith(ctx + "/resources/images/logo1.png%3bjsessionid=")||
+                    uri.startsWith(ctx + "/resources/images/logo1.png%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml;jsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3bjsessionid=")||
+                    uri.startsWith(ctx + "/javax.faces.resource/components.js.xhtml%3Bjsessionid=")||
+
+                    uri.startsWith(ctx + "/resources/images/logo.png;jsessionid=")||
+                    uri.startsWith(ctx + "/resources/images/logo.png%3bjsessionid=")||
+                    uri.startsWith(ctx + "/resources/images/logo.png%3Bjsessionid=")) {
+                return false;
+            }
+            return SEMICOLON.stream().anyMatch(uri::contains);
+        }
+        return false;
+    }
+
+    private boolean containsBackslash(String uri) {
+        if (isBlockBackslash()) {
+            return BACKSLASH.stream().anyMatch(uri::contains);
+        }
+        return false;
+    }
+
+    private boolean containsNonAsciiCharacters(String uri) {
+        if (isBlockNonAscii()) {
+            return !containsOnlyPrintableAsciiCharacters(uri);
+        }
+        return false;
+    }
+
+    private static boolean containsOnlyPrintableAsciiCharacters(String uri) {
+        int length = uri.length();
+        for (int i = 0; i < length; i++) {
+            char c = uri.charAt(i);
+            if (c < '\u0020' || c > '\u007e') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean isBlockSemicolon() {
+        return blockSemicolon;
+    }
+
+    public void setBlockSemicolon(boolean blockSemicolon) {
+        this.blockSemicolon = blockSemicolon;
+    }
+
+    public boolean isBlockBackslash() {
+        return blockBackslash;
+    }
+
+    public void setBlockBackslash(boolean blockBackslash) {
+        this.blockBackslash = blockBackslash;
+    }
+
+    public boolean isBlockNonAscii() {
+        return blockNonAscii;
+    }
+
+    public void setBlockNonAscii(boolean blockNonAscii) {
+        this.blockNonAscii = blockNonAscii;
+    }
+}

--
Gitblit v1.9.2