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 handleRuntimeException(RuntimeException e, WebRequest webRequest){ - List details = new ArrayList<>(); - details.add(e.getLocalizedMessage()); - ErrorResponse errorResponse = new ErrorResponse("Runtime Error", details); - return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); + public final Object handleRuntimeException(RuntimeException e, WebRequest webRequest){ + ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond(); + errorInfoJSONRespond.setDate(new Date()); + errorInfoJSONRespond.setExceptionMessage(e.getMessage()); + errorInfoJSONRespond.setException(e.getClass().getName()); + return errorInfoJSONRespond; } + + } diff --git a/src/main/java/com/codesdream/ase/controller/ASEErrorController.java b/src/main/java/com/codesdream/ase/controller/ASEErrorController.java index 124294f..ab33dc1 100644 --- a/src/main/java/com/codesdream/ase/controller/ASEErrorController.java +++ b/src/main/java/com/codesdream/ase/controller/ASEErrorController.java @@ -1,6 +1,8 @@ package com.codesdream.ase.controller; +import com.codesdream.ase.component.datamanager.QuickJSONRespond; import com.codesdream.ase.component.error.ErrorResponse; +import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -9,8 +11,10 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.WebRequest; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Date; @@ -19,7 +23,7 @@ import java.util.List; @Controller public class ASEErrorController implements ErrorController { - @RequestMapping("/error") +/* @RequestMapping("/error") public String handleError(HttpServletRequest request, Model model){ Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception"); @@ -49,7 +53,36 @@ public class ASEErrorController implements ErrorController { model.addAttribute("exception_date", new Date()); } return "error"; + }*/ + @Resource + private QuickJSONRespond quickJSONRespond; + + @RequestMapping("/error") + @ResponseBody + public String handleError(HttpServletRequest request){ + Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); + Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception"); + + // 检查返回的状态 + if (statusCode == HttpStatus.NOT_FOUND.value()) return quickJSONRespond.getRespond404(null); + ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond(); + + // 检查是否含有引发异常 + if (exception.getCause() == null) { + errorInfoJSONRespond.setException(exception.getClass().getName()); + errorInfoJSONRespond.setExceptionMessage(exception.getMessage()); + } else { + errorInfoJSONRespond.setException(exception.getCause().getClass().getName()); + errorInfoJSONRespond.setExceptionMessage(exception.getCause().getMessage()); + } + errorInfoJSONRespond.setDate(new Date()); + + return quickJSONRespond.getJSONStandardRespond( + statusCode, + "Error Controller Handle", + null, + errorInfoJSONRespond); } @Override diff --git a/src/main/java/com/codesdream/ase/controller/LoginController.java b/src/main/java/com/codesdream/ase/controller/LoginController.java index db99311..eb319aa 100644 --- a/src/main/java/com/codesdream/ase/controller/LoginController.java +++ b/src/main/java/com/codesdream/ase/controller/LoginController.java @@ -2,6 +2,7 @@ package com.codesdream.ase.controller; import com.alibaba.fastjson.JSONObject; import com.codesdream.ase.component.datamanager.JSONParameter; +import com.codesdream.ase.component.datamanager.QuickJSONRespond; import com.codesdream.ase.component.json.respond.JSONStandardFailedRespond; import com.codesdream.ase.component.json.respond.JSONBaseRespondObject; import com.codesdream.ase.component.permission.ASEUsernameEncoder; @@ -30,6 +31,9 @@ public class LoginController { @Resource private JSONParameter jsonParameter; + @Resource + private QuickJSONRespond quickJSONRespond; + @Resource private IUserService userService; @@ -61,11 +65,11 @@ public class LoginController { // 构造返回对象 UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond(); respond.setUserExist(existStatus); - return jsonParameter.getJSONString(respond); + return quickJSONRespond.getRespond200(null, respond); } else { // 返回失败对象 - return jsonParameter.getJSONString(new JSONStandardFailedRespond()); + return quickJSONRespond.getRespond400("CheckType Mismatch"); } } @@ -81,12 +85,12 @@ public class LoginController { if(loginChecker.getCheckType().equals("UIDGeneratorChecker")) { UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond(); - respond.setRespondInformation(userService.getUsernameByStudentId(loginChecker.getUsername())); - return jsonParameter.getJSONString(respond); + respond.setUid(userService.getUsernameByStudentId(loginChecker.getUsername())); + return quickJSONRespond.getRespond200(null, respond); } else { // 返回失败对象 - return jsonParameter.getJSONString(new JSONStandardFailedRespond()); + return quickJSONRespond.getRespond400("CheckType Mismatch"); } diff --git a/src/main/java/com/codesdream/ase/controller/RegisterController.java b/src/main/java/com/codesdream/ase/controller/RegisterController.java index 01a4835..77b126b 100644 --- a/src/main/java/com/codesdream/ase/controller/RegisterController.java +++ b/src/main/java/com/codesdream/ase/controller/RegisterController.java @@ -1,5 +1,8 @@ package com.codesdream.ase.controller; +import com.codesdream.ase.component.datamanager.JSONParameter; +import com.codesdream.ase.component.datamanager.QuickJSONRespond; +import com.codesdream.ase.component.json.request.UserRegisterChecker; import com.codesdream.ase.model.information.BaseStudentInfo; import com.codesdream.ase.model.permission.User; import com.codesdream.ase.service.BaseInformationService; @@ -8,18 +11,25 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import java.util.Map; +import java.util.Optional; @Controller public class RegisterController { @Resource - UserService userService; + private UserService userService; @Resource - BaseInformationService baseInformationService; + private BaseInformationService baseInformationService; + + @Resource + private JSONParameter jsonParameter; + + @Resource + private QuickJSONRespond quickJSONRespond; @RequestMapping(value = "/register") String registerView(Model model){ @@ -27,55 +37,61 @@ public class RegisterController { } // 处理注册表单 - @PostMapping(value = "/register") - String doRegister(Model model, HttpServletRequest request){ - Map parameterMap= request.getParameterMap(); + @PostMapping(value = "/register/do_register") + @ResponseBody + String doRegister(HttpServletRequest request){ - // 进行处理前的检查 - if(parameterMap.containsKey("student-id") - && parameterMap.containsKey("password") - && parameterMap.containsKey("retry-password") - && parameterMap.containsKey("user-question") - && parameterMap.containsKey("user-answer") - ) { - // 获得提交学号 - String student_id = parameterMap.get("student-id")[0].toString(); - // 获得密保问题 - String user_question = parameterMap.get("user-question")[0].toString(); - // 获得密保答案 - String user_answer = parameterMap.get("user-answer")[0].toString(); - - // 检查用户的基本信息是否录入系统 - if(!baseInformationService.checkStudentInfo(student_id)) - throw new RuntimeException("Student ID Not Found In Base Information Service"); - - // 查找对应的基本信息 - BaseStudentInfo studentInfo = baseInformationService.findStudentInfoByStudentId(student_id); - - // 根据基本信息生成对应用户 - User user = userService.getUserByStudentInfo(studentInfo); - - // 填充密保问题 - user.getUserAuth().setUserQuestion(user_question); - user.getUserAuth().setUserAnswer(user_answer); - user.getUserAuth().setMail(""); - - String password = parameterMap.get("password")[0].toString(); - String retry_password = parameterMap.get("retry-password")[0].toString(); - - if (password.equals(retry_password)) { - user.setPassword(password); - userService.save(user); - // 返回登录界面 - return "login"; - } - else{ - throw new RuntimeException("Retry Password Not Correct"); - } + Optional registerCheckerOptional = + jsonParameter.getJavaObjectByRequest(request, UserRegisterChecker.class); + // 检查JSON是否完整 + if(!registerCheckerOptional.isPresent()){ + return quickJSONRespond.getRespond400("Illegal JSON Format"); } - return "register"; + // 检查数据是否完整 + UserRegisterChecker registerChecker = registerCheckerOptional.get(); + if(registerChecker.getPassword() == null + || registerChecker.getStudentId() == null + || registerChecker.getUserAnswer() == null + || registerChecker.getUserQuestion() == null){ + return quickJSONRespond.getRespond400("Incomplete Data"); + } + + // 获得提交学号 + String student_id = registerChecker.getStudentId(); + // 获得密保问题 + String user_question = registerChecker.getUserQuestion(); + // 获得密保答案 + String user_answer = registerChecker.getUserAnswer(); + + // 检查用户的基本信息是否录入系统 + if(!baseInformationService.checkStudentInfo(student_id)) + return quickJSONRespond.getRespond500("StudentID Base Information Not Found"); + + // 检查学号是否已被注册 + if(userService.checkIfUserExists(userService.getUsernameByStudentId(student_id)).getKey()){ + return quickJSONRespond.getRespond500("StudentID Already Used"); + } + + // 查找对应的基本信息 + BaseStudentInfo studentInfo = baseInformationService.findStudentInfoByStudentId(student_id); + + // 根据基本信息生成对应用户 + User user = userService.getUserByStudentInfo(studentInfo); + + // 填充密保问题 + user.getUserAuth().setUserQuestion(user_question); + user.getUserAuth().setUserAnswer(user_answer); + user.getUserAuth().setMail(""); + + String password = registerChecker.getPassword(); + + user.setPassword(password); + userService.save(user); + + // 成功注册 + return quickJSONRespond.getRespond200("Register Success"); } } diff --git a/src/main/java/com/codesdream/ase/service/ASEUserDetailsService.java b/src/main/java/com/codesdream/ase/service/ASEUserDetailsService.java index 411bcbb..2d9a666 100644 --- a/src/main/java/com/codesdream/ase/service/ASEUserDetailsService.java +++ b/src/main/java/com/codesdream/ase/service/ASEUserDetailsService.java @@ -1,7 +1,9 @@ package com.codesdream.ase.service; import com.codesdream.ase.component.permission.UserAuthoritiesGenerator; +import com.codesdream.ase.exception.UserNotFoundException; import com.codesdream.ase.model.permission.User; +import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -21,9 +23,14 @@ public class ASEUserDetailsService implements UserDetailsService { @Override @Transactional - public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { - User user = userService.findUserByUsername(s); - user.setAuthorities(userAuthoritiesGenerator.grantedAuthorities(user)); - return user; + public UserDetails loadUserByUsername(String s) { + try { + User user = userService.findUserByUsername(s); + user.setAuthorities(userAuthoritiesGenerator.grantedAuthorities(user)); + return user; + } catch (UserNotFoundException e){ + throw new AuthenticationServiceException("User Not Exist"); + } + } } diff --git a/src/main/java/com/codesdream/ase/service/BaseInformationService.java b/src/main/java/com/codesdream/ase/service/BaseInformationService.java index 870a816..072ec94 100644 --- a/src/main/java/com/codesdream/ase/service/BaseInformationService.java +++ b/src/main/java/com/codesdream/ase/service/BaseInformationService.java @@ -20,25 +20,25 @@ import java.util.Vector; public class BaseInformationService implements IBaseInformationService { @Resource - BaseAdministrativeDivisionRepository administrativeDivisionRepository; + private BaseAdministrativeDivisionRepository administrativeDivisionRepository; @Resource - BaseCandidateCategoryRepository candidateCategoryRepository; + private BaseCandidateCategoryRepository candidateCategoryRepository; @Resource - BaseCollegeRepository collegeRepository; + private BaseCollegeRepository collegeRepository; @Resource - BaseEthnicRepository ethnicRepository; + private BaseEthnicRepository ethnicRepository; @Resource - BaseMajorRepository majorRepository; + private BaseMajorRepository majorRepository; @Resource - BasePoliticalStatusRepository politicalStatusRepository; + private BasePoliticalStatusRepository politicalStatusRepository; @Resource - BaseStudentInfoRepository studentInfoRepository; + private BaseStudentInfoRepository studentInfoRepository; @Override public boolean checkAdministrativeDivision(String name) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ef36be0..8693bdc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,13 +8,14 @@ spring.thymeleaf.encoding=UTF-8 spring.jpa.generate-ddl=false spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update -spring.jooq.sql-dialect=org.hibernate.dialect.MySQL5InnoDBDialect +spring.jooq.sql-dialect=org.hibernate.dialect.MariaDB102Dialect spring.jpa.open-in-view=true spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true -spring.datasource.url=jdbc:mysql://${MYSQL_HOST:119.23.9.34}:3306/ase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC +spring.datasource.url=jdbc:mariadb://39.100.94.111:3306/ase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=codedream spring.datasource.password=codedreampasswd +spring.datasource.driver-class-name=org.mariadb.jdbc.Driver server.error.whitelabel.enabled=false