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 9b5dced..954850b 100644
--- a/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java
+++ b/src/main/java/com/codesdream/ase/component/auth/JSONRandomCodeGenerator.java
@@ -6,13 +6,14 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
+// 随机特征码生成器
@Component
public class JSONRandomCodeGenerator {
@Resource
private SHA1Encoder encoder;
- public String generateRandomCode(String username, Date date, String apiSHA1){
+ public String generateRandomCode(String username, Date date, String clientCode){
return encoder.encode(String.format("RandomCode [%s][%s][%s]",
- username, date.toString(), apiSHA1));
+ username, date.toString(), clientCode));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/auth/JSONTokenAuthenticationToken.java b/src/main/java/com/codesdream/ase/component/auth/JSONTokenAuthenticationToken.java
index cafc05d..92bf5f9 100644
--- a/src/main/java/com/codesdream/ase/component/auth/JSONTokenAuthenticationToken.java
+++ b/src/main/java/com/codesdream/ase/component/auth/JSONTokenAuthenticationToken.java
@@ -7,14 +7,15 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
-// 关联Token与其他用户的相关数据的认证对象
+// 关联Token与其他用户的相关数据的授权柄
public class JSONTokenAuthenticationToken extends AbstractAuthenticationToken {
- // token 产生的签名
- String signed = null;
+ // 客户端签名
+ private String signed = null;
// 用户名
- Object principal = null;
- // JSON 特征随机代码
- String randomCode = null;
+ private Object principal = null;
+ // 客户端代码
+ private String clientCode = null;
+
/**
* Creates a token with the supplied array of authorities.
@@ -22,18 +23,21 @@ public class JSONTokenAuthenticationToken extends AbstractAuthenticationToken {
* @param authorities the collection of GrantedAuthoritys for the principal
* represented by this authentication object.
*/
- public JSONTokenAuthenticationToken(UserDetails principal, String signed, Collection extends GrantedAuthority> authorities) {
+ public JSONTokenAuthenticationToken(UserDetails principal,
+ String clientCode,
+ Collection extends GrantedAuthority> authorities)
+ {
super(authorities);
this.principal = principal;
- this.randomCode = null;
- this.signed = signed;
+ this.clientCode = clientCode;
+ this.signed = null;
setAuthenticated(true);
}
- public JSONTokenAuthenticationToken(String principal, String randomCode, String signed) {
+ public JSONTokenAuthenticationToken(String principal, String clientCode, String signed) {
super(null);
this.principal = principal;
- this.randomCode = randomCode;
+ this.clientCode = clientCode;
this.signed = signed;
setAuthenticated(false);
}
@@ -48,11 +52,11 @@ public class JSONTokenAuthenticationToken extends AbstractAuthenticationToken {
return principal;
}
- public String getRandomCode() {
- return randomCode;
+ public String getClientCode() {
+ return clientCode;
}
- public void setRandomCode(String randomCode) {
- this.randomCode = randomCode;
+ public void setClientCode(String clientCode) {
+ this.clientCode = clientCode;
}
}
diff --git a/src/main/java/com/codesdream/ase/component/auth/JSONTokenUsernamePasswordAuthenticationToken.java b/src/main/java/com/codesdream/ase/component/auth/JSONTokenUsernamePasswordAuthenticationToken.java
new file mode 100644
index 0000000..14cc5fd
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/auth/JSONTokenUsernamePasswordAuthenticationToken.java
@@ -0,0 +1,38 @@
+package com.codesdream.ase.component.auth;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+// 明文用户名密码验证授权柄
+public class JSONTokenUsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
+ // 用户名
+ private String username = null;
+ // 明文密码
+ private String password = null;
+ // 授权柄
+ private String clientCode = null;
+
+ public JSONTokenUsernamePasswordAuthenticationToken(String username, String password, String clientCode) {
+ super(null);
+ this.username = username;
+ this.password = password;
+ this.clientCode = clientCode;
+ setAuthenticated(false);
+ }
+
+ @Override
+ public Object getCredentials() {
+ return password;
+ }
+
+ @Override
+ public Object getPrincipal() {
+ return username;
+ }
+ // 扩展接口 获得客户端代码
+ public String getClientCode() {
+ return clientCode;
+ }
+}
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 726d4e4..103c5a0 100644
--- a/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java
+++ b/src/main/java/com/codesdream/ase/component/datamanager/JSONParameter.java
@@ -2,9 +2,11 @@ package com.codesdream.ase.component.datamanager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
@@ -56,6 +58,38 @@ 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);
@@ -67,4 +101,6 @@ public class JSONParameter {
return json.map(jsonObject -> getJavaObject(jsonObject, type));
}
+
+
}
diff --git a/src/main/java/com/codesdream/ase/component/json/request/UserLoginChecker.java b/src/main/java/com/codesdream/ase/component/json/request/UserLoginChecker.java
index 4f82267..0f706cf 100644
--- a/src/main/java/com/codesdream/ase/component/json/request/UserLoginChecker.java
+++ b/src/main/java/com/codesdream/ase/component/json/request/UserLoginChecker.java
@@ -8,9 +8,6 @@ public class UserLoginChecker {
private String checkType;
private String username;
private String password;
+ private String clientCode;
-// // 客户端类型
-// private String clientType;
-// // JSON签名
-// private String signed;
}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/EmptyDataObjectRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/EmptyDataObjectRespond.java
new file mode 100644
index 0000000..e3ae905
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/json/respond/EmptyDataObjectRespond.java
@@ -0,0 +1,5 @@
+package com.codesdream.ase.component.json.respond;
+
+public class EmptyDataObjectRespond {
+
+}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/FailedSONRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/FailedSONRespond.java
deleted file mode 100644
index e0c6de7..0000000
--- a/src/main/java/com/codesdream/ase/component/json/respond/FailedSONRespond.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.codesdream.ase.component.json.respond;
-
-// 请求失败返回JSON
-public class FailedSONRespond extends JSONBaseRespondObject {
- public FailedSONRespond(){
- super();
- this.status = "fail";
- }
-}
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 dd624d9..f180023 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
@@ -2,20 +2,57 @@ package com.codesdream.ase.component.json.respond;
import com.codesdream.ase.component.json.JSONBaseObject;
import lombok.Data;
+import lombok.EqualsAndHashCode;
import java.util.Date;
// 服务端返回的JSON对象模板
+@EqualsAndHashCode(callSuper = true)
@Data
public class JSONBaseRespondObject extends JSONBaseObject {
- // 请求成功状态
- String status = "fail";
- public JSONBaseRespondObject(){
+ // 存放返回内容
+ private Object data = new EmptyDataObjectRespond();
+ // 存放响应信息提示
+ private String msg = "";
+
+ // 状态
+ private Integer status = 200;
+
+ public JSONBaseRespondObject(String msg){
+ super();
+ this.status = 200;
+ this.msg = msg;
}
- public JSONBaseRespondObject(String status){
+ public JSONBaseRespondObject(Integer status, String msg){
+ super();
this.status = status;
+ this.msg = msg;
+ }
+
+ public void setStatusNotFound(){
+ this.status = 404;
+ }
+
+ public void setStatusBadRequest(){
+ this.status = 400;
+ }
+
+ public void setStatusUnauthorized(){
+ this.status = 401;
+ }
+
+ public void setStatusForbidden(){
+ this.status = 403;
+ }
+
+ public void setStatusInternalServerError(){
+ this.status = 500;
+ }
+
+ public void setStatusOK(){
+ this.status = 200;
}
}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/JSONStandardFailedRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/JSONStandardFailedRespond.java
new file mode 100644
index 0000000..ba1626f
--- /dev/null
+++ b/src/main/java/com/codesdream/ase/component/json/respond/JSONStandardFailedRespond.java
@@ -0,0 +1,8 @@
+package com.codesdream.ase.component.json.respond;
+
+// 请求失败返回JSON
+public class JSONStandardFailedRespond extends JSONBaseRespondObject {
+ public JSONStandardFailedRespond(){
+ super(500, "failed");
+ }
+}
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 e4112ca..79ccfe9 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
@@ -3,17 +3,12 @@ package com.codesdream.ase.component.json.respond;
import lombok.Data;
import lombok.EqualsAndHashCode;
-@EqualsAndHashCode(callSuper = true)
@Data
-public class UserLoginCheckerJSONRespond extends JSONBaseRespondObject {
+public class UserLoginCheckerJSONRespond {
boolean userExist = false;
boolean loginStatus = false;
boolean userBanned = false;
String respondInformation = "";
String token = "";
- public UserLoginCheckerJSONRespond(){
- super("success");
- }
-
}
diff --git a/src/main/java/com/codesdream/ase/component/json/respond/UserLoginTokenJSONRespond.java b/src/main/java/com/codesdream/ase/component/json/respond/UserLoginTokenJSONRespond.java
index 48b087e..43272ab 100644
--- a/src/main/java/com/codesdream/ase/component/json/respond/UserLoginTokenJSONRespond.java
+++ b/src/main/java/com/codesdream/ase/component/json/respond/UserLoginTokenJSONRespond.java
@@ -1,6 +1,6 @@
package com.codesdream.ase.component.json.respond;
// 返回登录后的授权码(用于客户端生成签名)
-public class UserLoginTokenJSONRespond extends JSONBaseRespondObject {
+public class UserLoginTokenJSONRespond {
String token;
}
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 caf783c..3e62a3f 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.json.respond.JSONBaseRespondObject;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
@@ -23,18 +24,8 @@ public class ASEAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
- log.info("ASEAuthenticationEntryPoint Found!");
-
- response.setCharacterEncoding("utf-8");
- response.setContentType("text/javascript;charset=utf-8");
- UserLoginCheckerJSONRespond checkerRespond = new UserLoginCheckerJSONRespond();
- checkerRespond.setLoginStatus(false);
- checkerRespond.setUserExist(false);
- checkerRespond.setUserBanned(true);
- checkerRespond.setRespondInformation("Anonymous user has no access to this resource");
-
- // 对匿名用户返回
- response.getWriter().print(jsonParameter.getJSONString(checkerRespond));
+ // 对匿名用户返回403
+ response.getWriter().print(jsonParameter.getJSONStandardRespond403());
}
}
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 86ab588..1680ec3 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationFailureHandler.java
@@ -33,6 +33,6 @@ public class ASEAuthenticationFailureHandler extends SimpleUrlAuthenticationFail
respond.setRespondInformation("Authentication Failed");
// 填充response对象
- response.getWriter().write(jsonParameter.getJSONString(respond));
+ response.getWriter().write(jsonParameter.getJSONStandardRespond200(respond));
}
}
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 d8ea606..9abed5f 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEAuthenticationSuccessHandler.java
@@ -1,5 +1,6 @@
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.json.respond.UserLoginCheckerJSONRespond;
import com.codesdream.ase.model.permission.User;
@@ -35,31 +36,26 @@ public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthentica
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException
{
- // 对AJAX登录请求特殊化处理
-/*
- if(Optional.ofNullable(request.getHeader("X-Requested-With")).isPresent()) {
- HttpSession session = request.getSession();
- SecurityContext securityContext = SecurityContextHolder.getContext();
-
- session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
- }
-*/
UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
respond.setUserExist(authentication.isAuthenticated());
respond.setLoginStatus(authentication.isAuthenticated());
+ respond.setRespondInformation("Authentication Success");
+
+ // 获得 JSONTokenAuthenticationToken
+ JSONTokenAuthenticationToken authenticationToken = (JSONTokenAuthenticationToken) authentication;
+
+ User user = (User) authenticationToken.getPrincipal();
+
+ Optional tokenOptional = authService.userNewTokenGetter(
+ user.getUsername(), authenticationToken.getClientCode());
- // 获得session id
- /*WebAuthenticationDetails webAuthenticationDetails = (WebAuthenticationDetails) (authentication.getDetails());*/
- User user = (User) authentication.getPrincipal();
- // 获得api token
- Optional tokenOptional = authService.userNewTokenGetter(user.getUsername());
if(tokenOptional.isPresent()){
respond.setToken(tokenOptional.get());
}
else respond.setToken("");
- response.getWriter().write(jsonParameter.getJSONString(respond));
+ response.getWriter().write(jsonParameter.getJSONStandardRespond200(respond));
}
}
diff --git a/src/main/java/com/codesdream/ase/component/permission/ASEJSONTokenAuthenticationFilter.java b/src/main/java/com/codesdream/ase/component/permission/ASEJSONTokenAuthenticationFilter.java
index d22ec0d..a518944 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEJSONTokenAuthenticationFilter.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEJSONTokenAuthenticationFilter.java
@@ -1,29 +1,18 @@
package com.codesdream.ase.component.permission;
-import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.auth.AJAXRequestChecker;
import com.codesdream.ase.component.auth.JSONRandomCodeGenerator;
import com.codesdream.ase.component.auth.JSONSignedGenerator;
import com.codesdream.ase.component.auth.JSONTokenAuthenticationToken;
import com.codesdream.ase.component.datamanager.JSONParameter;
-import com.codesdream.ase.exception.JSONTokenExpiredException;
-import com.codesdream.ase.exception.JSONTokenIncorrectSignedException;
import com.codesdream.ase.model.auth.JSONToken;
import com.codesdream.ase.service.AuthService;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.authentication.AuthenticationServiceException;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
-import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
@@ -32,7 +21,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.nio.file.attribute.UserPrincipalNotFoundException;
import java.util.Collection;
import java.util.Date;
import java.util.Optional;
@@ -64,56 +52,68 @@ public class ASEJSONTokenAuthenticationFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
+ // 用户名
String username = request.getHeader( "username");
+ // 客户端签名
String signed = request.getHeader("signed");
- String rawDate = request.getHeader("date");
+ // 时间戳
+ String timestamp = request.getHeader("timestamp");
- // 对API的内容取哈希码
- String apiSHA1 = request.getHeader("apiSHA1");
-
- if (signed != null && username != null && rawDate != null && apiSHA1 != null) {
+ if (signed != null && username != null && timestamp != null) {
// 获得具体时间
- Date date = new Date(Long.parseLong(rawDate));
+ Date date = new Date(Long.parseLong(timestamp));
- // 检查时间是否合理
- // ...
+ Date now = new Date();
- // 生成特征随机代码
- String randomCode = randomCodeGenerator.generateRandomCode(username, date, apiSHA1);
+ // 限制时间戳有效区间为60s
+ long dtTime = 60*1000;
+ Date maxDate = new Date(now.getTime() + dtTime);
- // 进行验证
- Optional optionalJSONToken = authService.findTokenByUserName(username);
- if(!optionalJSONToken.isPresent()){
- throw new UserPrincipalNotFoundException("Token Not Found");
- }
+ // 检查时间戳是否合理
+ if(maxDate.after(date)) {
+ // 从服务器中查找token
+ Optional optionalJSONToken = authService.findTokenByUserName(username);
+ if (optionalJSONToken.isPresent()) {
+ JSONToken token = optionalJSONToken.get();
- // 检查token是否过期
- JSONToken token = optionalJSONToken.get();
- if(!authService.checkTokenIfExpired(token)) {
+ // 检查token是否过期
+ if (!authService.checkTokenIfExpired(token)) {
+ // 生成特征随机代码
+ String randomCode = randomCodeGenerator.generateRandomCode(username, date, token.getClientCode());
- log.info(String.format("Determined Signed: %s",
- signedGenerator.generateSigned(username, randomCode, token.getToken())));
+ log.info(String.format("Determined Signed: %s",
+ signedGenerator.generateSigned(username, randomCode, token.getToken())));
- // 检查签名是否正确
- if (signed.equals(signedGenerator.generateSigned(username, randomCode, token.getToken()))) {
-
- // 查询用户的相关信息
- UserDetails user = userDetailsService.loadUserByUsername(username);
-
- Collection extends GrantedAuthority> authorities = user.getAuthorities();
-
- // 生成认证柄 (储存上下文信息)
- JSONTokenAuthenticationToken authentication = new JSONTokenAuthenticationToken(user, signed, authorities);
- authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-
- SecurityContextHolder.getContext().setAuthentication(authentication);
+ // 检查签名是否正确
+ if (signed.equals(signedGenerator.generateSigned(username, randomCode, token.getToken()))) {
+ // 执行授权操作
+ doAuthentication(username, request);
+ }
+ }
}
}
-
}
filterChain.doFilter(request, response);
}
+ // 执行授权
+ private void doAuthentication(String username, HttpServletRequest request){
+ // 查询用户的相关信息
+ UserDetails user = userDetailsService.loadUserByUsername(username);
+
+ // 生成用户权限列表
+ Collection extends GrantedAuthority> authorities = user.getAuthorities();
+
+ // 生成授权柄 (储存上下文信息)
+ JSONTokenAuthenticationToken authentication =
+ new JSONTokenAuthenticationToken(user, null, authorities);
+
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+
+ // 执行授权
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+
}
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 9bf6a94..7ba70ca 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASESecurityAuthenticationProvider.java
@@ -1,5 +1,7 @@
package com.codesdream.ase.component.permission;
+import com.codesdream.ase.component.auth.JSONTokenAuthenticationToken;
+import com.codesdream.ase.component.auth.JSONTokenUsernamePasswordAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
@@ -29,10 +31,15 @@ public class ASESecurityAuthenticationProvider implements AuthenticationProvider
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+ JSONTokenUsernamePasswordAuthenticationToken authenticationToken =
+ (JSONTokenUsernamePasswordAuthenticationToken) authentication;
+
// 获得登录表单中的学号
- String username = usernameEncoder.encode(authentication.getName());
+ String username = usernameEncoder.encode((CharSequence) authenticationToken.getPrincipal());
// 获得表单中的密码
- String password = passwordEncoder.encode(authentication.getCredentials().toString());
+ String password = passwordEncoder.encode((CharSequence) authenticationToken.getCredentials());
+ // 获得
+ String clientCode = authenticationToken.getClientCode();
// 判断用户是否存在
UserDetails userInfo = userDetailsService.loadUserByUsername(username);
@@ -58,12 +65,14 @@ public class ASESecurityAuthenticationProvider implements AuthenticationProvider
throw new AccountExpiredException("User IS Expired");
}
+ // 生成权限列表
Collection extends GrantedAuthority> authorities = userInfo.getAuthorities();
- return new UsernamePasswordAuthenticationToken(userInfo, password, authorities);
+
+ return new JSONTokenAuthenticationToken(userInfo, clientCode, authorities);
}
@Override
public boolean supports(Class> aClass) {
- return aClass.equals(UsernamePasswordAuthenticationToken.class);
+ return aClass.equals(JSONTokenUsernamePasswordAuthenticationToken.class);
}
}
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 2868d42..2be84dd 100644
--- a/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java
+++ b/src/main/java/com/codesdream/ase/component/permission/ASEUsernamePasswordAuthenticationFilter.java
@@ -1,6 +1,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.datamanager.JSONParameter;
import com.codesdream.ase.component.json.request.UserLoginChecker;
import lombok.extern.slf4j.Slf4j;
@@ -10,6 +11,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@@ -32,19 +34,19 @@ public class ASEUsernamePasswordAuthenticationFilter extends UsernamePasswordAut
// 判断是否为AJAX请求格式的数据
if(!ajaxRequestChecker.checkAjaxPOSTRequest(request)) {
- log.info("NOT AJAX POST 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");
- log.info("JSON Object 2 Java Object Success.");
+
if (!checker.get().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();
if (username == null) username = "";
if (password == null) password = "";
@@ -53,15 +55,12 @@ public class ASEUsernamePasswordAuthenticationFilter extends UsernamePasswordAut
username = username.trim();
password = password.trim();
- UsernamePasswordAuthenticationToken authRequest =
- new UsernamePasswordAuthenticationToken(username, password);
+ JSONTokenUsernamePasswordAuthenticationToken authRequest =
+ new JSONTokenUsernamePasswordAuthenticationToken(username, password, clientCode);
- log.info(String.format("User AJAX JSON Authentication: %s %s.", username, password));
-
- setDetails(request, authRequest);
+ authRequest.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
return this.getAuthenticationManager().authenticate(authRequest);
-
}
}
diff --git a/src/main/java/com/codesdream/ase/controller/LoginController.java b/src/main/java/com/codesdream/ase/controller/LoginController.java
index 9796ea7..db99311 100644
--- a/src/main/java/com/codesdream/ase/controller/LoginController.java
+++ b/src/main/java/com/codesdream/ase/controller/LoginController.java
@@ -2,7 +2,7 @@ package com.codesdream.ase.controller;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.datamanager.JSONParameter;
-import com.codesdream.ase.component.json.respond.FailedSONRespond;
+import com.codesdream.ase.component.json.respond.JSONStandardFailedRespond;
import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
import com.codesdream.ase.component.permission.ASEUsernameEncoder;
import com.codesdream.ase.component.json.request.UserLoginChecker;
@@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.security.Principal;
import java.util.Optional;
@@ -48,7 +47,7 @@ public class LoginController {
// 检查是否为JSON
Optional json = jsonParameter.getJSONByRequest(request);
- if(!json.isPresent()) return jsonParameter.getJSONString(new FailedSONRespond());
+ if(!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
UserLoginChecker loginChecker = json.get().toJavaObject(UserLoginChecker.class);
@@ -66,7 +65,7 @@ public class LoginController {
}
else {
// 返回失败对象
- return jsonParameter.getJSONString(new JSONBaseRespondObject());
+ return jsonParameter.getJSONString(new JSONStandardFailedRespond());
}
}
@@ -76,7 +75,7 @@ public class LoginController {
String checkUsernameByStudentID(HttpServletRequest request){
// 检查是否为JSON
Optional json = jsonParameter.getJSONByRequest(request);
- if(!json.isPresent()) return jsonParameter.getJSONString(new FailedSONRespond());
+ if(!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
UserLoginChecker loginChecker = json.get().toJavaObject(UserLoginChecker.class);
@@ -87,7 +86,7 @@ public class LoginController {
}
else {
// 返回失败对象
- return jsonParameter.getJSONString(new JSONBaseRespondObject());
+ return jsonParameter.getJSONString(new JSONStandardFailedRespond());
}
diff --git a/src/main/java/com/codesdream/ase/model/auth/JSONToken.java b/src/main/java/com/codesdream/ase/model/auth/JSONToken.java
index e88c51b..751ebf1 100644
--- a/src/main/java/com/codesdream/ase/model/auth/JSONToken.java
+++ b/src/main/java/com/codesdream/ase/model/auth/JSONToken.java
@@ -23,6 +23,9 @@ public class JSONToken {
@Column(unique = true)
private String token;
+ // 客户端标识口令
+ private String clientCode;
+
// token过期时间
private Date expiredDate;
}
diff --git a/src/main/java/com/codesdream/ase/service/AuthService.java b/src/main/java/com/codesdream/ase/service/AuthService.java
index f88aff7..1784365 100644
--- a/src/main/java/com/codesdream/ase/service/AuthService.java
+++ b/src/main/java/com/codesdream/ase/service/AuthService.java
@@ -36,18 +36,24 @@ public class AuthService implements IAuthService {
}
@Override
- public Optional userNewTokenGetter(String username) {
+ public Optional userNewTokenGetter(String username, String clientCode) {
Pair userPair = userService.checkIfUserExists(username);
if(userPair.getKey()){
Optional jsonTokenOptional = jsonTokenRepository.findByUsername(username);
JSONToken token = jsonTokenOptional.orElseGet(JSONToken::new);
+
// 过期时间设置为三十分钟后
long currentTime = System.currentTimeMillis();
currentTime +=30*60*1000;
token.setExpiredDate(new Date(currentTime));
token.setToken(authTokenGenerator.generateAuthToken(username));
+
+
// 设置用户名
token.setUsername(username);
+ // 设置客户端代号
+ token.setClientCode(clientCode);
+
// 在数据库中更新新的token
token = jsonTokenRepository.save(token);
return Optional.ofNullable(token.getToken());
diff --git a/src/main/java/com/codesdream/ase/service/IAuthService.java b/src/main/java/com/codesdream/ase/service/IAuthService.java
index a3f6a7b..fc4eae0 100644
--- a/src/main/java/com/codesdream/ase/service/IAuthService.java
+++ b/src/main/java/com/codesdream/ase/service/IAuthService.java
@@ -12,5 +12,5 @@ public interface IAuthService {
boolean checkTokenIfExpired(JSONToken token);
// 为用户获得一个新的API Token
- Optional userNewTokenGetter(String username);
+ Optional userNewTokenGetter(String username, String clientCode);
}