Pārlūkot izejas kodu

fix shiro filter

张延森 3 gadus atpakaļ
vecāks
revīzija
f49585223c

+ 2
- 2
src/main/java/com/yunzhi/nanyang/controller/LoginController.java Parādīt failu

@@ -86,8 +86,8 @@ public class LoginController extends BaseController {
86 86
 
87 87
     @GetMapping("/401")
88 88
     @ApiOperation(value="401无权限", notes = "401无权限", httpMethod = "GET", response = ResponseBean.class)
89
-    public ResponseBean unAuth() throws Exception {
90
-        return ResponseBean.error("未登录或暂无权限", ResponseBean.ERROR_AUTH_FAIL);
89
+    public ResponseBean unAuth(@RequestParam(value = "msg", defaultValue = "未登录或暂无权限") String msg) throws Exception {
90
+        return ResponseBean.error(msg, ResponseBean.ERROR_AUTH_FAIL);
91 91
     }
92 92
 
93 93
 //    @PutMapping("/admin/change-password")

+ 25
- 5
src/main/java/com/yunzhi/nanyang/shiro/filters/JWTFilter.java Parādīt failu

@@ -2,6 +2,7 @@ package com.yunzhi.nanyang.shiro.filters;
2 2
 
3 3
 import com.yunzhi.nanyang.shiro.utils.JWTToken;
4 4
 import com.yunzhi.nanyang.shiro.utils.JWTUtil;
5
+import org.apache.shiro.authc.AuthenticationException;
5 6
 import org.apache.shiro.authc.AuthenticationToken;
6 7
 import org.apache.shiro.subject.Subject;
7 8
 import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
@@ -13,6 +14,8 @@ import javax.servlet.ServletRequest;
13 14
 import javax.servlet.ServletResponse;
14 15
 import javax.servlet.http.HttpServletResponse;
15 16
 import java.io.IOException;
17
+import java.io.UnsupportedEncodingException;
18
+import java.net.URLEncoder;
16 19
 
17 20
 public class JWTFilter extends AuthenticatingFilter {
18 21
 
@@ -38,13 +41,21 @@ public class JWTFilter extends AuthenticatingFilter {
38 41
         return new JWTToken(authorization);
39 42
     }
40 43
 
44
+    @Override
45
+    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
46
+        AuthenticationToken token = this.createToken(request, response);
47
+        Subject subject = this.getSubject(request, response);
48
+        subject.login(token);
49
+        return this.onLoginSuccess(token, subject, request, response);
50
+    }
51
+
41 52
     @Override
42 53
     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
43 54
         boolean allowed = false;
44 55
         try {
45 56
             allowed = executeLogin(request, response);
46 57
         } catch (Exception e) {
47
-            response401(request, response);
58
+            response401(request, response, e);
48 59
         }
49 60
 
50 61
         return allowed;
@@ -73,11 +84,20 @@ public class JWTFilter extends AuthenticatingFilter {
73 84
     /**
74 85
      *Jump illegal request to / 401
75 86
      */
76
-    private void response401(ServletRequest request, ServletResponse response) {
87
+    private void response401(ServletRequest request, ServletResponse response, Exception e) {
88
+        String message = "";
89
+        if (e != null) {
90
+            try {
91
+                message = URLEncoder.encode(e.getMessage(), "UTF-8");
92
+            } catch (UnsupportedEncodingException ex) {
93
+                //
94
+            }
95
+        }
96
+
77 97
         try {
78
-            WebUtils.toHttp(response).sendRedirect(unauthorizedUrl);
79
-        } catch (IOException e) {
80
-            LOGGER.error(e.getMessage());
98
+            WebUtils.toHttp(response).sendRedirect(unauthorizedUrl + "?msg=" + message);
99
+        } catch (IOException e1) {
100
+            LOGGER.error(e1.getMessage());
81 101
         }
82 102
     }
83 103
 }

+ 5
- 3
src/main/java/com/yunzhi/nanyang/shiro/matcher/JWTCredentialsMatcher.java Parādīt failu

@@ -1,6 +1,5 @@
1 1
 package com.yunzhi.nanyang.shiro.matcher;
2 2
 
3
-import com.yunzhi.nanyang.shiro.utils.JWTUtil;
4 3
 import org.apache.shiro.authc.AuthenticationInfo;
5 4
 import org.apache.shiro.authc.AuthenticationToken;
6 5
 import org.apache.shiro.authc.credential.CredentialsMatcher;
@@ -8,7 +7,10 @@ import org.apache.shiro.authc.credential.CredentialsMatcher;
8 7
 public class JWTCredentialsMatcher implements CredentialsMatcher {
9 8
     @Override
10 9
     public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) {
11
-        String token = authenticationToken.getCredentials().toString();
12
-        return JWTUtil.verify(token);
10
+//        String token = authenticationToken.getCredentials().toString();
11
+//        return JWTUtil.verify(token);
12
+
13
+        // 校验在 realm 做过了
14
+        return true;
13 15
     }
14 16
 }

+ 18
- 5
src/main/java/com/yunzhi/nanyang/shiro/realms/manager/ManagerRealm.java Parādīt failu

@@ -1,11 +1,10 @@
1 1
 package com.yunzhi.nanyang.shiro.realms.manager;
2 2
 
3
+import com.auth0.jwt.exceptions.JWTDecodeException;
4
+import com.auth0.jwt.exceptions.TokenExpiredException;
3 5
 import com.yunzhi.nanyang.shiro.utils.JWTToken;
4 6
 import com.yunzhi.nanyang.shiro.utils.JWTUtil;
5
-import org.apache.shiro.authc.AuthenticationException;
6
-import org.apache.shiro.authc.AuthenticationInfo;
7
-import org.apache.shiro.authc.AuthenticationToken;
8
-import org.apache.shiro.authc.SimpleAuthenticationInfo;
7
+import org.apache.shiro.authc.*;
9 8
 import org.apache.shiro.authz.AuthorizationInfo;
10 9
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
11 10
 import org.apache.shiro.realm.AuthorizingRealm;
@@ -43,10 +42,24 @@ public class ManagerRealm extends AuthorizingRealm {
43 42
     @Override
44 43
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
45 44
         String token = (String) authenticationToken.getPrincipal();
45
+
46
+        // 这里进行 token 验证, CredentialsMatcher 就不做了
47
+        try {
48
+            JWTUtil.verify(token);
49
+        } catch (JWTDecodeException e1) {
50
+            throw new AuthenticationException("非法的权限凭证");
51
+        } catch (TokenExpiredException e2) {
52
+            throw new ExpiredCredentialsException("授权过期, 请重新登录");
53
+        } catch (Exception e) {
54
+            e.printStackTrace();
55
+            throw new AuthenticationException("凭证校验失败, 请重新登录");
56
+        }
57
+
58
+
46 59
         String loginId = JWTUtil.getLoginId(token);
47 60
 
48 61
         if (!iManagerService.verify(loginId)) {
49
-            throw new AuthenticationException("User is abnormal");
62
+            throw new LockedAccountException("用户不存在或者状态异常");
50 63
         }
51 64
 
52 65
         // 交给 AuthenticatingRealm 使用 CredentialsMatcher 行校验

+ 9
- 8
src/main/java/com/yunzhi/nanyang/shiro/utils/JWTUtil.java Parādīt failu

@@ -3,7 +3,9 @@ package com.yunzhi.nanyang.shiro.utils;
3 3
 import com.auth0.jwt.JWT;
4 4
 import com.auth0.jwt.algorithms.Algorithm;
5 5
 import com.auth0.jwt.exceptions.JWTDecodeException;
6
+import com.auth0.jwt.exceptions.JWTVerificationException;
6 7
 import com.auth0.jwt.interfaces.DecodedJWT;
8
+import com.auth0.jwt.interfaces.JWTVerifier;
7 9
 
8 10
 import java.util.Date;
9 11
 
@@ -52,14 +54,13 @@ public class JWTUtil {
52 54
         return sign(loginId, secret);
53 55
     }
54 56
 
55
-    public static boolean verify(String token) {
56
-        try {
57
-            JWT.decode(token);
58
-            return true;
59
-        } catch (Exception e) {
60
-            e.printStackTrace();
61
-            return false;
62
-        }
57
+    public static void verify(String token) throws JWTVerificationException {
58
+        DecodedJWT jwt = JWT.decode(token);
59
+        String loginId = jwt.getSubject();
60
+        String secret = jwt.getClaim("secret").asString();
61
+        Algorithm algorithm = Algorithm.HMAC256(secret);
62
+        JWTVerifier verifier = JWT.require(algorithm).withSubject(loginId).build();
63
+        verifier.verify(jwt);
63 64
     }
64 65
 
65 66
 }