diff --git a/pom.xml b/pom.xml
index b66f69d..aaa6cb5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,6 +138,13 @@
1.1.71.android
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ 2.5.4
+
+
+
diff --git a/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java b/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java
index 954850b..fe2ce6c 100644
--- a/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java
+++ b/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java
@@ -14,6 +14,6 @@ public class JSONRandomCodeGenerator {
public String generateRandomCode(String username, Date date, String clientCode){
return encoder.encode(String.format("RandomCode [%s][%s][%s]",
- username, date.toString(), clientCode));
+ username, Long.toString(date.getTime()), clientCode));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/auth/TimestampExpiredChecker.java b/src/main/java/com/codesdream/ase/component/auth/TimestampExpiredChecker.java
new file mode 100644
index 0000000..080bd20
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/auth/TimestampExpiredChecker.java
@@ -0,0 +1,18 @@
+package com.codesdream.ase.component.auth;
+
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+// 验证时间戳是否有效
+@Component
+public class TimestampExpiredChecker {
+
+ public boolean checkTimestampBeforeMaxTime(String timestamp, int seconds){
+ Date timestampDate = new Date(Long.parseLong(timestamp));
+ long currentTime = System.currentTimeMillis();
+ Date maxDate = new Date(currentTime + seconds * 1000);
+ return timestampDate.before(maxDate);
+ }
+
+}
diff --git a/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java b/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java
index 103c5a0..dbce1a6 100644
--- a/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java
+++ b/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java
@@ -58,38 +58,6 @@ public class JSONParameter {
return JSON.toJSONString(object);
}
- // 根据对象构造获得标准的JSON响应字符串返回
- public String getJSONStandardRespond(Integer status, String msg, Object dataObject){
- JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status, msg);
- respondObject.setData(dataObject);
- return getJSONString(respondObject);
- }
-
- // 获得标准的JSON响应字符串返回(404状态)
- public String getJSONStandardRespond404(String msg){
- JSONBaseRespondObject respondObject = new JSONBaseRespondObject(404, msg);
- return getJSONString(respondObject);
- }
-
- // 获得标准的JSON响应字符串返回(500状态)
- public String getJSONStandardRespond500(String msg){
- JSONBaseRespondObject respondObject = new JSONBaseRespondObject(500, msg);
- return getJSONString(respondObject);
- }
-
- // 获得标准的JSON响应字符串返回(200状态)
- public String getJSONStandardRespond200(Object dataObject){
- JSONBaseRespondObject respondObject = new JSONBaseRespondObject(200, "ok");
- respondObject.setData(dataObject);
- return getJSONString(respondObject);
- }
-
- // 获得标准的JSON响应字符串返回(403状态)
- public String getJSONStandardRespond403(){
- JSONBaseRespondObject respondObject = new JSONBaseRespondObject(403, "forbidden");
- return getJSONString(respondObject);
- }
-
// 由JSON对象获得对应的Java对象
public T getJavaObject(JSONObject json, Class type){
return json.toJavaObject(type);
diff --git a/src/main/java/com/codesdream/ase/component/datamanager/QuickJSONRespond.java b/src/main/java/com/codesdream/ase/component/datamanager/QuickJSONRespond.java
new file mode 100644
index 0000000..ab2d6ab
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/datamanager/QuickJSONRespond.java
@@ -0,0 +1,80 @@
+package com.codesdream.ase.component.datamanager;
+
+import com.codesdream.ase.component.json.respond.EmptyDataObjectRespond;
+import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+
+@Component
+public class QuickJSONRespond {
+ @Resource
+ private JSONParameter jsonParameter;
+
+ // 根据对象构造获得标准的JSON响应字符串返回
+ public String getJSONStandardRespond(Integer status, String msg, String info, Object dataObject){
+ JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status, msg);
+ if(info != null) respondObject.setInfo(info);
+ else respondObject.setInfo(null);
+
+ respondObject.setData(dataObject);
+ return jsonParameter.getJSONString(respondObject);
+ }
+
+ // 获得标准的JSON响应字符串返回特定状态码的和解释息
+ public String getJSONStandardRespond(Integer code, String msg, String info){
+ JSONBaseRespondObject respondObject = new JSONBaseRespondObject(code, msg);
+ if(info != null) respondObject.setInfo(info);
+ else respondObject.setInfo(null);
+ respondObject.setData(null);
+ return jsonParameter.getJSONString(respondObject);
+ }
+
+ // 获得标准的JSON响应字符串返回(404状态)
+ public String getRespond404(String info){
+ return getJSONStandardRespond(404, "Not Found", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(500状态)
+ public String getRespond500(String info){
+ return getJSONStandardRespond(500, "Internal Server Error", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(200状态)
+ public String getRespond200(String info){
+ return getJSONStandardRespond(200, "Ok", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(200状态)
+ public String getRespond200(String info, Object object){
+ return getJSONStandardRespond(200, "Ok", info, object);
+ }
+
+ // 获得标准的JSON响应字符串返回(403状态)
+ public String getRespond403(String info){
+ return getJSONStandardRespond(403, "Forbidden", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(403状态)
+ public String getRespond406(String info){
+ return getJSONStandardRespond(406, "Not Acceptable", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(501态)
+ public String getRespond501(String info){
+ return getJSONStandardRespond(501, "Not Implemented", info) ;
+ }
+
+ // 获得标准的JSON响应字符串返回(401状态)
+ public String getRespond401(String info){
+ return getJSONStandardRespond(401, "Unauthorized", info);
+ }
+
+ // 获得标准的JSON响应字符串返回(400状态)
+ public String getRespond400(String info){
+ return getJSONStandardRespond(400, "Bad Request", info);
+ }
+
+
+}
diff --git a/src/main/java/com/codesdream/ase/component/json/request/UserRegisterChecker.java b/src/main/java/com/codesdream/ase/component/json/request/UserRegisterChecker.java
new file mode 100644
index 0000000..491cda6
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/json/request/UserRegisterChecker.java
@@ -0,0 +1,19 @@
+package com.codesdream.ase.component.json.request;
+
+import lombok.Data;
+
+@Data
+public class UserRegisterChecker {
+
+ // 学号
+ private String studentId;
+
+ // 密码
+ private String password;
+
+ // 密保问题
+ private String userQuestion;
+
+ // 密保答案
+ private String userAnswer;
+}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/ErrorInfoJSONRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/ErrorInfoJSONRespond.java
new file mode 100644
index 0000000..4495e20
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/json/respond/ErrorInfoJSONRespond.java
@@ -0,0 +1,12 @@
+package com.codesdream.ase.component.json.respond;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ErrorInfoJSONRespond {
+ String exception = null;
+ String exceptionMessage = null;
+ Date date = null;
+}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/JSONBaseRespondObject.java b/src/main/java/com/codesdream/ase/component/json/respond/JSONBaseRespondObject.java
index f180023..d1a2d2f 100644
--- a/src/main/java/com/codesdream/ase/component/json/respond/JSONBaseRespondObject.java
+++ b/src/main/java/com/codesdream/ase/component/json/respond/JSONBaseRespondObject.java
@@ -17,6 +17,9 @@ public class JSONBaseRespondObject extends JSONBaseObject {
// 存放响应信息提示
private String msg = "";
+ // 额外信息
+ private String info = null;
+
// 状态
private Integer status = 200;
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/UserLoginCheckerJSONRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/UserLoginCheckerJSONRespond.java
index 79ccfe9..6cbaeed 100644
--- a/src/main/java/com/codesdream/ase/component/json/respond/UserLoginCheckerJSONRespond.java
+++ b/src/main/java/com/codesdream/ase/component/json/respond/UserLoginCheckerJSONRespond.java
@@ -1,14 +1,16 @@
package com.codesdream.ase.component.json.respond;
+import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
public class UserLoginCheckerJSONRespond {
- boolean userExist = false;
- boolean loginStatus = false;
- boolean userBanned = false;
- String respondInformation = "";
- String token = "";
+ Boolean userExist = null;
+ Boolean userBanned = null;
+ Boolean loginStatus = null;
+ String respondInformation = null;
+ String token = null;
+ String uid = null;
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEAccessDeniedHandler.java b/src/main/java/com/codesdream/ase/component/permission/ASEAccessDeniedHandler.java
index 2043f27..48405bb 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAccessDeniedHandler.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAccessDeniedHandler.java
@@ -1,6 +1,7 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.component.datamanager.JSONParameter;
+import com.codesdream.ase.component.datamanager.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
@@ -19,22 +20,16 @@ import java.io.IOException;
public class ASEAccessDeniedHandler implements AccessDeniedHandler {
@Resource
- private JSONParameter jsonParameter;
+ private QuickJSONRespond quickJSONRespond;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException {
log.info("ASEAccessDeniedHandler Found!");
- response.setCharacterEncoding("utf-8");
- response.setContentType("text/javascript;charset=utf-8");
- UserLoginCheckerJSONRespond checkerRespond = new UserLoginCheckerJSONRespond();
- checkerRespond.setLoginStatus(true);
- checkerRespond.setUserExist(true);
- checkerRespond.setRespondInformation("Authenticated user has no access to this resource");
+ // 对无权限操作返回403
+ response.getWriter().print(quickJSONRespond.getRespond403(null));
- // 对匿名用户返回
- response.getWriter().print(jsonParameter.getJSONString(checkerRespond));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationEntryPoint.java b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationEntryPoint.java
index 3e62a3f..b3f5962 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationEntryPoint.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationEntryPoint.java
@@ -1,6 +1,7 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.component.datamanager.JSONParameter;
+import com.codesdream.ase.component.datamanager.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import lombok.extern.slf4j.Slf4j;
@@ -19,13 +20,14 @@ import java.io.IOException;
@Component
public class ASEAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Resource
- private JSONParameter jsonParameter;
+ private QuickJSONRespond quickJSONRespond;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
- throws IOException, ServletException {
- // 对匿名用户返回403
- response.getWriter().print(jsonParameter.getJSONStandardRespond403());
+ throws IOException {
+
+ // 对匿名用户返回401
+ response.getWriter().print(quickJSONRespond.getRespond401(null));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java
index 1680ec3..ee82950 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java
@@ -1,6 +1,8 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.component.datamanager.JSONParameter;
+import com.codesdream.ase.component.datamanager.QuickJSONRespond;
+import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
@@ -12,6 +14,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.util.Date;
// 认证失败返回
@Slf4j
@@ -19,20 +22,25 @@ import java.io.IOException;
public class ASEAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Resource
- private JSONParameter jsonParameter;
+ private QuickJSONRespond quickJSONRespond;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
- throws IOException, ServletException
+ throws IOException
{
log.info("ASEAuthenticationFailureHandler Login Fail!");
- UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
- respond.setUserExist(false);
- respond.setLoginStatus(false);
- respond.setUserBanned(true);
- respond.setRespondInformation("Authentication Failed");
- // 填充response对象
- response.getWriter().write(jsonParameter.getJSONStandardRespond200(respond));
+ // 填写异常信息存储对象
+ ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond();
+ errorInfoJSONRespond.setDate(new Date());
+ errorInfoJSONRespond.setExceptionMessage(exception.getMessage());
+ errorInfoJSONRespond.setException(exception.getClass().getSimpleName());
+
+ // 认证失败返回406
+ response.getWriter().write(quickJSONRespond.getJSONStandardRespond(
+ 406,
+ "Not Acceptable",
+ "Authentication Failure",
+ errorInfoJSONRespond));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java
index 9abed5f..857e4b5 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java
@@ -2,6 +2,7 @@ package com.codesdream.ase.component.permission;
import com.codesdream.ase.component.auth.JSONTokenAuthenticationToken;
import com.codesdream.ase.component.datamanager.JSONParameter;
+import com.codesdream.ase.component.datamanager.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import com.codesdream.ase.model.permission.User;
@@ -27,7 +28,7 @@ import java.util.Optional;
@Component
public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Resource
- private JSONParameter jsonParameter;
+ private QuickJSONRespond quickJSONRespond;
@Resource
private IAuthService authService;
@@ -40,7 +41,6 @@ public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthentica
UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
respond.setUserExist(authentication.isAuthenticated());
respond.setLoginStatus(authentication.isAuthenticated());
- respond.setRespondInformation("Authentication Success");
// 获得 JSONTokenAuthenticationToken
JSONTokenAuthenticationToken authenticationToken = (JSONTokenAuthenticationToken) authentication;
@@ -55,7 +55,8 @@ public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthentica
}
else respond.setToken("");
- response.getWriter().write(jsonParameter.getJSONStandardRespond200(respond));
+ // 认证成功返回200
+ response.getWriter().write(quickJSONRespond.getRespond200("Authentication Success", respond));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java b/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java
index 7ba70ca..61edbd5 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java
@@ -43,10 +43,8 @@ public class ASESecurityAuthenticationProvider implements AuthenticationProvider
// 判断用户是否存在
UserDetails userInfo = userDetailsService.loadUserByUsername(username);
- log.info(String.format("SecurityAuthentication: %s %s", username, password));
-
if (userInfo == null) {
- throw new UsernameNotFoundException("User IS Not Existing");
+ throw new UsernameNotFoundException("User Not Exist");
}
// 判断密码是否正确
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java b/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java
index 2be84dd..6f6acb0 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java
@@ -2,6 +2,7 @@ package com.codesdream.ase.component.permission;
import com.codesdream.ase.component.auth.AJAXRequestChecker;
import com.codesdream.ase.component.auth.JSONTokenUsernamePasswordAuthenticationToken;
+import com.codesdream.ase.component.auth.TimestampExpiredChecker;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.request.UserLoginChecker;
import lombok.extern.slf4j.Slf4j;
@@ -12,6 +13,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@@ -28,25 +30,43 @@ public class ASEUsernamePasswordAuthenticationFilter extends UsernamePasswordAut
@Resource
private AJAXRequestChecker ajaxRequestChecker;
+ @Resource
+ private TimestampExpiredChecker timestampExpiredChecker;
+
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
+ String timestamp = request.getHeader("timestamp");
+
+ // 检查时间戳是否合理(60秒内)
+ if(timestamp == null || !timestampExpiredChecker.checkTimestampBeforeMaxTime(timestamp, 60)){
+ throw new AuthenticationServiceException("Timestamp Expired.");
+ }
+
// 判断是否为AJAX请求格式的数据
if(!ajaxRequestChecker.checkAjaxPOSTRequest(request)) {
throw new AuthenticationServiceException("Authentication method not supported: NOT Ajax Method.");
}
- Optional checker = jsonParameter.getJavaObjectByRequest(request, UserLoginChecker.class);
- if(!checker.isPresent()) throw new BadCredentialsException("Invalid AJAX JSON Request");
+ Optional checkerOptional = jsonParameter.getJavaObjectByRequest(request, UserLoginChecker.class);
+ if(!checkerOptional.isPresent()) throw new BadCredentialsException("Invalid AJAX JSON Request");
- if (!checker.get().getCheckType().equals("UsernamePasswordChecker"))
+ UserLoginChecker checker = checkerOptional.get();
+
+ if(checker.getUsername() == null
+ || checker.getPassword() == null
+ || checker.getClientCode() == null
+ || checker.getCheckType() == null)
+ throw new AuthenticationServiceException("Request Data IS Incomplete");
+
+ if (!checker.getCheckType().equals("UsernamePasswordChecker"))
throw new AuthenticationServiceException("Authentication not supported: NOT Username Password Type.");
// 获得相应的用户名密码
- String username = checker.get().getUsername();
- String password = checker.get().getPassword();
- String clientCode = checker.get().getClientCode();
+ String username = checker.getUsername();
+ String password = checker.getPassword();
+ String clientCode = checker.getClientCode();
if (username == null) username = "";
if (password == null) password = "";
diff --git a/src/main/java/com/codesdream/ase/controller/ASEControllerAdvice.java b/src/main/java/com/codesdream/ase/controller/ASEControllerAdvice.java
index d5166ff..332f5ba 100644
--- a/src/main/java/com/codesdream/ase/controller/ASEControllerAdvice.java
+++ b/src/main/java/com/codesdream/ase/controller/ASEControllerAdvice.java
@@ -1,23 +1,31 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.component.error.ErrorResponse;
+import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
-@ControllerAdvice
+@RestControllerAdvice
public class ASEControllerAdvice {
@ExceptionHandler(value = {RuntimeException.class})
- public final ResponseEntity