From 05556708ff94c71dc2924d2f380f1bb1561b05da Mon Sep 17 00:00:00 2001 From: huoyo <1729913829@qq.com> Date: Sat, 12 Feb 2022 16:19:12 +0800 Subject: [PATCH] update auth --- NOTICE | 2 + pom.xml | 7 +- .../kotime/controller/KoTimeController.java | 67 ++++++++++--------- .../cn/langpy/kotime/handler/AuthHandler.java | 13 +++- .../java/cn/langpy/kotime/util/KoUtil.java | 53 ++++++++------- src/main/resources/kotime.html | 33 +++++---- 6 files changed, 105 insertions(+), 70 deletions(-) diff --git a/NOTICE b/NOTICE index 6d77232..acd9415 100644 --- a/NOTICE +++ b/NOTICE @@ -3,4 +3,6 @@ Copyright 2020 KoTime This product contains UIkit developed by YOOtheme. +This product uses Java JWT(com.auth0:java-jwt:3.16.0). + This product includes software developed at The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 15f9bc7..bcf2b07 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.langpy ko-time - 2.0.4 + 2.0.6-PRE koTime koTime @@ -23,6 +23,11 @@ scm:git:https://gitee.com/huoyo/ko-time.git + + com.auth0 + java-jwt + 3.16.0 + org.springframework spring-context diff --git a/src/main/java/cn/langpy/kotime/controller/KoTimeController.java b/src/main/java/cn/langpy/kotime/controller/KoTimeController.java index af2467f..77e94a4 100644 --- a/src/main/java/cn/langpy/kotime/controller/KoTimeController.java +++ b/src/main/java/cn/langpy/kotime/controller/KoTimeController.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; + /** * zhangchang */ @@ -37,37 +38,40 @@ public class KoTimeController { @PostMapping("/login") @ResponseBody - public Map login(@RequestBody UserInfo userInfo) { - if (null==userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) { + public Map login(@RequestBody UserInfo userInfo) { + if (null == userInfo || !StringUtils.hasText(userInfo.getUserName()) || !StringUtils.hasText(userInfo.getPassword())) { throw new InvalidAuthInfoException("failed to login for kotime,please fill userName and password!"); } Map map = new HashMap(); if (userName.equals(userInfo.getUserName()) && password.equals(userInfo.getPassword())) { - KoUtil.login(userInfo.getUserName()); - map.put("state",1); + String token = KoUtil.login(userInfo.getUserName()); + map.put("state", 1); + map.put("token", token); return map; } - map.put("state",0); + map.put("state", 0); return map; } - @PostMapping("/logout") + @GetMapping("/isLogin") @ResponseBody - public Map logout() { - KoUtil.logout(); + public Map isLogin(String token) { Map map = new HashMap(); - map.put("state",1); + map.put("state", 1); + boolean checkLogin = KoUtil.isLogin(token); + map.put("isLogin", checkLogin ? 1 : 0); return map; } + @GetMapping - public void index(String test,HttpServletResponse response, HttpServletRequest request) throws Exception { - if (null!=test) { + public void index(String test, HttpServletResponse response, HttpServletRequest request) throws Exception { + if (null != test) { return; } response.setContentType("text/html;charset=utf-8"); ClassPathResource classPathResource = new ClassPathResource(KoConstant.kotimeViewer); - BufferedReader reader = new BufferedReader(new InputStreamReader(classPathResource.getInputStream(),"utf-8")); + BufferedReader reader = new BufferedReader(new InputStreamReader(classPathResource.getInputStream(), "utf-8")); PrintWriter out = response.getWriter(); String context = request.getContextPath(); if (StringUtils.hasText(Context.getConfig().getContextPath())) { @@ -76,22 +80,20 @@ public class KoTimeController { StringBuilder stringBuilder = new StringBuilder(); String line = ""; int n = 0; - while((line = reader.readLine()) != null) { - if (n>14) { - if (line.indexOf(KoConstant.globalThreshold)>-1) { - line = line.replace(KoConstant.globalThreshold,Context.getConfig().getThreshold()+""); - }else if (line.indexOf(KoConstant.globalNeedLogin)>-1) { - line = line.replace(KoConstant.globalNeedLogin,Context.getConfig().getAuthEnable()+""); - }else if (line.indexOf(KoConstant.globalIsLogin)>-1) { - line = line.replace(KoConstant.globalIsLogin,KoUtil.isLogin()+""); - }else if (line.indexOf(KoConstant.contextPath)>-1) { - line = line.replace(KoConstant.contextPath,context); - }else if (line.indexOf(KoConstant.exceptionTitleStyle)>-1) { - line = line.replace(KoConstant.exceptionTitleStyle,Context.getConfig().getExceptionEnable()==true?"":"display:none;"); + while ((line = reader.readLine()) != null) { + if (n > 14) { + if (line.indexOf(KoConstant.globalThreshold) > -1) { + line = line.replace(KoConstant.globalThreshold, Context.getConfig().getThreshold() + ""); + } else if (line.indexOf(KoConstant.globalNeedLogin) > -1) { + line = line.replace(KoConstant.globalNeedLogin, Context.getConfig().getAuthEnable() + ""); + } else if (line.indexOf(KoConstant.contextPath) > -1) { + line = line.replace(KoConstant.contextPath, context); + } else if (line.indexOf(KoConstant.exceptionTitleStyle) > -1) { + line = line.replace(KoConstant.exceptionTitleStyle, Context.getConfig().getExceptionEnable() == true ? "" : "display:none;"); } - stringBuilder.append(line+"\n"); - }else { - stringBuilder.append(line+"\n"); + stringBuilder.append(line + "\n"); + } else { + stringBuilder.append(line + "\n"); } n++; } @@ -125,12 +127,13 @@ public class KoTimeController { List list = null; if (StringUtils.hasText(question)) { list = graphService.searchMethods(question); - }else { + } else { list = graphService.getControllers(); } Collections.sort(list); return list; } + @GetMapping("/getApiTips") @ResponseBody @Auth @@ -171,16 +174,16 @@ public class KoTimeController { @Auth public boolean updateConfig(@RequestBody DefaultConfig config) { DefaultConfig koTimeConfig = Context.getConfig(); - if (config.getEnable()!=null) { + if (config.getEnable() != null) { koTimeConfig.setEnable(config.getEnable()); } - if (config.getExceptionEnable()!=null) { + if (config.getExceptionEnable() != null) { koTimeConfig.setExceptionEnable(config.getExceptionEnable()); } - if (config.getLogEnable()!=null) { + if (config.getLogEnable() != null) { koTimeConfig.setLogEnable(config.getLogEnable()); } - if (config.getThreshold()!=null) { + if (config.getThreshold() != null) { koTimeConfig.setThreshold(config.getThreshold()); } return true; diff --git a/src/main/java/cn/langpy/kotime/handler/AuthHandler.java b/src/main/java/cn/langpy/kotime/handler/AuthHandler.java index 9a557ec..b570349 100644 --- a/src/main/java/cn/langpy/kotime/handler/AuthHandler.java +++ b/src/main/java/cn/langpy/kotime/handler/AuthHandler.java @@ -3,6 +3,7 @@ package cn.langpy.kotime.handler; import cn.langpy.kotime.annotation.Auth; import cn.langpy.kotime.constant.KoConstant; import cn.langpy.kotime.util.Context; +import cn.langpy.kotime.util.KoTimeNotLoginException; import cn.langpy.kotime.util.KoUtil; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -10,7 +11,11 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.logging.Logger; @@ -31,7 +36,13 @@ public class AuthHandler { Method method = ((MethodSignature) pjp.getSignature()).getMethod(); boolean needAuth = method.isAnnotationPresent(Auth.class); if (needAuth&& Context.getConfig().getAuthEnable()) { - KoUtil.checkLogin(); + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String token = request.getParameter("token"); + if (StringUtils.hasText(token)) { + KoUtil.checkLogin(token); + }else { + throw new KoTimeNotLoginException("can not find login information for kotime,please login first!"); + } } return pjp.proceed(); } diff --git a/src/main/java/cn/langpy/kotime/util/KoUtil.java b/src/main/java/cn/langpy/kotime/util/KoUtil.java index e19a18d..2e235a4 100644 --- a/src/main/java/cn/langpy/kotime/util/KoUtil.java +++ b/src/main/java/cn/langpy/kotime/util/KoUtil.java @@ -1,42 +1,49 @@ package cn.langpy.kotime.util; -import cn.langpy.kotime.constant.KoConstant; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import java.util.Date; public class KoUtil { + private static final String koTimeSecret = "KotimeLang"; - public static void login(String userName) { - getSession().setAttribute(KoConstant.loginName, userName); + public static String login(String userName) { + Algorithm algorithm = Algorithm.HMAC256(koTimeSecret); + String token = JWT.create() + .withIssuer("kotime") + .withSubject(userName) + .withExpiresAt(new Date(System.currentTimeMillis() + (12*60*60*1000))) + .withClaim("author", "KoTime") + .sign(algorithm); + return token; } - public static void logout() { - getSession().removeAttribute(KoConstant.loginName); - } - public static void checkLogin() { - Object userName = getSession().getAttribute(KoConstant.loginName); - if (null == userName) { + public static boolean checkLogin(String token) { + try { + Algorithm algorithm = Algorithm.HMAC256(koTimeSecret); + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + return true; + }catch (JWTVerificationException verificationException){ throw new KoTimeNotLoginException("can not find login information for kotime,please login first!"); } } - public static boolean isLogin() { - Object userName = getSession().getAttribute(KoConstant.loginName); - if (null == userName) { + public static boolean isLogin(String token) { + try { + Algorithm algorithm = Algorithm.HMAC256(koTimeSecret); + JWTVerifier verifier = JWT.require(algorithm).build(); + DecodedJWT jwt = verifier.verify(token); + return true; + }catch (JWTVerificationException verificationException){ return false; } - return true; } - private static HttpSession getSession() { - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - HttpServletRequest request = attributes.getRequest(); - HttpSession session = request.getSession(); - return session; - } } diff --git a/src/main/resources/kotime.html b/src/main/resources/kotime.html index 98e2dcb..3076663 100644 --- a/src/main/resources/kotime.html +++ b/src/main/resources/kotime.html @@ -20,13 +20,19 @@ var d = 180; var globalThreshold = globalThresholdValue; var globalNeedLogin = globalNeedLoginValue; - var globalIsLogin = globalIsLoginValue; + var globalToken = sessionStorage.getItem("kotimeToken") $(document).ready(function () { + let globalIsLogin = false; + $.ajaxSettings.async = false; + $.get('contextPath/koTime/isLogin?token='+globalToken, function (data) { + globalIsLogin = data['isLogin']==1?true:false; + }); + $.ajaxSettings.async = true; if (globalNeedLogin==true && globalIsLogin == false) { UIkit.modal(document.getElementById("modal-login")).show(); return; }; - $.get('contextPath/koTime/getConfig', function (data) { + $.get('contextPath/koTime/getConfig?token='+globalToken, function (data) { let exceptionEnable = data['exceptionEnable']; let exceptionEnableDom = document.getElementById('exceptionEnable'); @@ -51,24 +57,24 @@ }); document.getElementById('kotimeEnable').onclick = function(){ - $.ajax({type:'POST',url:'contextPath/koTime/updateConfig',data:JSON.stringify({enable:document.getElementById('kotimeEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); + $.ajax({type:'POST',url:'contextPath/koTime/updateConfig?token='+globalToken,data:JSON.stringify({enable:document.getElementById('kotimeEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); }; document.getElementById('exceptionEnable').onclick = function(){ - $.ajax({type:'POST',url:'contextPath/koTime/updateConfig',data:JSON.stringify({exceptionEnable:document.getElementById('exceptionEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); + $.ajax({type:'POST',url:'contextPath/koTime/updateConfig?token='+globalToken,data:JSON.stringify({exceptionEnable:document.getElementById('exceptionEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); }; document.getElementById('logEnable').onclick = function(){ - $.ajax({type:'POST',url:'contextPath/koTime/updateConfig',data:JSON.stringify({logEnable:document.getElementById('logEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); + $.ajax({type:'POST',url:'contextPath/koTime/updateConfig?token='+globalToken,data:JSON.stringify({logEnable:document.getElementById('logEnable').checked}),dataType:'json', headers: {'Content-Type': 'application/json' }}); }; document.getElementById("timeThresholdYes").onclick = function(){ - $.ajax({type:'POST',url:'contextPath/koTime/updateConfig',data:JSON.stringify({threshold:document.getElementById('timeThreshold').value}),dataType:'json', headers: {'Content-Type': 'application/json' }}); + $.ajax({type:'POST',url:'contextPath/koTime/updateConfig?token='+globalToken,data:JSON.stringify({threshold:document.getElementById('timeThreshold').value}),dataType:'json', headers: {'Content-Type': 'application/json' }}); }; - $.get('contextPath/koTime/getStatistic', function (data) { + $.get('contextPath/koTime/getStatistic?token='+globalToken, function (data) { let totalNum = data['totalNum']; let systemTotalNum = document.getElementById("systemTotalNum"); systemTotalNum.innerHTML=systemTotalNum.innerHTML+"
"+totalNum; @@ -108,7 +114,7 @@ }); $.ajaxSettings.async = false; let searchText = $("#searchText").val(); - $.get('contextPath/koTime/getApis?question='+searchText, function (data) { + $.get('contextPath/koTime/getApis?question='+searchText+'&token='+globalToken, function (data) { let element = document.getElementById('apiList'); html = ''; for (let i = 0; i < data.length; i++) { @@ -121,7 +127,7 @@ }; element.innerHTML = html; }); - $.get('contextPath/koTime/getExceptions', function (data) { + $.get('contextPath/koTime/getExceptions?token='+globalToken, function (data) { let element = document.getElementById('exceptionList'); html = ''; for (let i = 0; i < data.length; i++) { @@ -171,7 +177,7 @@ UIkit.notification.closeAll(); UIkit.modal(document.getElementById("modal-method")).show(); - $.get('contextPath/koTime/getTree?methodName=' + name, function (data) { + $.get('contextPath/koTime/getTree?methodName=' + name+'&token='+globalToken, function (data) { let rootX = 100; let rootY = $(window).get(0).innerHeight / 2-50; data['x'] = rootX; @@ -183,7 +189,7 @@ }; function showExceptions(id) { - $.get('contextPath/koTime/getMethodsByExceptionId?exceptionId=' + id, function (data) { + $.get('contextPath/koTime/getMethodsByExceptionId?exceptionId=' + id+'&token='+globalToken, function (data) { let html = ''; for (let i = 0; i < data.length; i++) { html += @@ -223,6 +229,7 @@ if (re['state']==1) { UIkit.notification("登录成功",{}); UIkit.notification.closeAll() + sessionStorage.setItem("kotimeToken", re["token"]); location.reload(); }else { UIkit.notification("用户名或密码错误",{}); @@ -235,7 +242,7 @@ } function searchTip(e){ let question = $('#searchText').val() - $.get('contextPath/koTime/getApiTips?question='+question, function (data) { + $.get('contextPath/koTime/getApiTips?question='+question+'&token='+globalToken, function (data) { $("#condidates").html("") for (let i = 0; i < data.length; i++) { let name = data[i]; @@ -247,7 +254,7 @@ function searchApis(e) { if (e.keyCode == 13) { let question = $('#searchText').val() - $.get('contextPath/koTime/getApis?question='+question, function (data) { + $.get('contextPath/koTime/getApis?question='+question+'&token='+globalToken, function (data) { let element = document.getElementById('apiList'); html = ''; for (let i = 0; i < data.length; i++) {