From 00762fb4f483df1c1c9d5fa9abf3116efe84b3ab Mon Sep 17 00:00:00 2001 From: Li Haoyu Date: Fri, 20 Dec 2019 19:06:14 +0800 Subject: [PATCH] 代码重构; token添加过期功能; 添加只能一点登录功能; --- src/main/java/com/objecteye/config/AccessConfirmServiceImpl.java | 82 ---------------------------------------------------------------------------------- src/main/java/com/objecteye/config/AuthenticationHeadFilter.java | 24 +++++++++++++++++++++++- src/main/java/com/objecteye/config/AuthenticationLoginFilter.java | 1 + src/main/java/com/objecteye/config/AuthenticationProviderConfig.java | 1 + src/main/java/com/objecteye/config/AuthenticationToken.java | 56 -------------------------------------------------------- src/main/java/com/objecteye/config/LoginFailureHandler.java | 21 --------------------- src/main/java/com/objecteye/config/LoginSuccessHandler.java | 32 -------------------------------- src/main/java/com/objecteye/config/WebSecurityConfig.java | 8 ++++++++ src/main/java/com/objecteye/controller/UserController.java | 6 ++++++ src/main/java/com/objecteye/handle/LoginFailureHandler.java | 21 +++++++++++++++++++++ src/main/java/com/objecteye/handle/LoginSuccessHandler.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/objecteye/pojo/AuthenticationToken.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/objecteye/pojo/TokenUser.java | 11 +++++++++++ src/main/java/com/objecteye/pojo/UserGroup.java | 2 +- src/main/java/com/objecteye/service/impl/AccessConfirmServiceImpl.java | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/objecteye/service/impl/UserDetailServiceImpl.java | 27 +++++++++++++-------------- src/main/java/com/objecteye/service/impl/UserGroupServiceImpl.java | 10 ++++++++-- src/main/java/com/objecteye/utils/GlobalUtil.java | 4 ++++ 18 files changed, 289 insertions(+), 209 deletions(-) delete mode 100644 src/main/java/com/objecteye/config/AccessConfirmServiceImpl.java delete mode 100644 src/main/java/com/objecteye/config/AuthenticationToken.java delete mode 100644 src/main/java/com/objecteye/config/LoginFailureHandler.java delete mode 100644 src/main/java/com/objecteye/config/LoginSuccessHandler.java create mode 100644 src/main/java/com/objecteye/handle/LoginFailureHandler.java create mode 100644 src/main/java/com/objecteye/handle/LoginSuccessHandler.java create mode 100644 src/main/java/com/objecteye/pojo/AuthenticationToken.java create mode 100644 src/main/java/com/objecteye/service/impl/AccessConfirmServiceImpl.java diff --git a/src/main/java/com/objecteye/config/AccessConfirmServiceImpl.java b/src/main/java/com/objecteye/config/AccessConfirmServiceImpl.java deleted file mode 100644 index f90e732..0000000 --- a/src/main/java/com/objecteye/config/AccessConfirmServiceImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.objecteye.config; - -import com.objecteye.pojo.SpecialAuthenticationUrlConfig; -import com.objecteye.pojo.UserDetailsMsg; -import com.objecteye.pojo.UserGroup; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.data.mongodb.core.query.Query; -import org.springframework.security.authentication.AnonymousAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Component; -import org.springframework.util.AntPathMatcher; - -import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Component("accessConfirmService") -public class AccessConfirmServiceImpl { - - @Autowired - private MongoTemplate mongoTemplate; - - private AntPathMatcher antPathMatcher = new AntPathMatcher(); - - public boolean hasPermission(HttpServletRequest request, Authentication auth) { - // 匿名token不允许访问所有的接口 - if (auth instanceof AnonymousAuthenticationToken) { - return false; - } - - UserDetails user = (UserDetails) auth.getPrincipal(); - Map specialUrlAccessMap = queryUrlByUserName(user.getUsername()); - for (Map.Entry entry : specialUrlAccessMap.entrySet()) { - if (antPathMatcher.match(entry.getKey(), request.getRequestURI())) { - return entry.getValue(); - } - } - return true; - } - - /** - * 查询用户权限 - * - * @param userName 用户名 - * @return key: 需要权限的url; value: 是否可以访问 - */ - private Map queryUrlByUserName(String userName) { - List userDetailsMsgList = mongoTemplate.find(Query.query(Criteria.where("userName").is(userName)), UserDetailsMsg.class); - Map specialUrlLevelMap = new HashMap<>(); - if (userDetailsMsgList.size() > 0) { - List levelList = new ArrayList<>(); - UserDetailsMsg userDetailsMsg = userDetailsMsgList.get(0); - levelList.add(userDetailsMsg.getUserRole()); - List userGroups = mongoTemplate.find(Query.query(Criteria.where("grouoId").is(userDetailsMsg.getGroup())), UserGroup.class); - if (userGroups.size() > 0) { - levelList.add(userGroups.get(0).getGroupLevel()); - } - // 保存的是所有的需要特殊权限才能访问的 - List specialUrlList = mongoTemplate.find(new Query(), SpecialAuthenticationUrlConfig.class); - if (specialUrlList.size() > 0) { - for (SpecialAuthenticationUrlConfig specialUrlConfig : specialUrlList) { - String url = specialUrlConfig.getUrl(); - Integer level = specialUrlConfig.getLevel(); - if (specialUrlLevelMap.containsKey(url)) { - // 历史数据不允许访问, 当前数据允许访问则刷新是否可以访问的状态 - if (!specialUrlLevelMap.get(url) && levelList.contains(level)) { - specialUrlLevelMap.put(url, true); - } - } else { - specialUrlLevelMap.put(url, levelList.contains(level)); - } - } - } - } - return specialUrlLevelMap; - } -} diff --git a/src/main/java/com/objecteye/config/AuthenticationHeadFilter.java b/src/main/java/com/objecteye/config/AuthenticationHeadFilter.java index 67f99a2..984f2af 100644 --- a/src/main/java/com/objecteye/config/AuthenticationHeadFilter.java +++ b/src/main/java/com/objecteye/config/AuthenticationHeadFilter.java @@ -1,7 +1,10 @@ package com.objecteye.config; import com.alibaba.fastjson.JSON; +import com.objecteye.pojo.AuthenticationToken; import com.objecteye.pojo.TokenUser; +import com.objecteye.utils.GlobalUtil; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.jwt.Jwt; import org.springframework.security.jwt.JwtHelper; @@ -22,6 +25,12 @@ public class AuthenticationHeadFilter extends OncePerRequestFilter { private RsaVerifier rsaVerifier; + private RedisTemplate redisTemplate; + + public void setRedisTemplate(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + public void setRsaVerifier(RsaVerifier rsaVerifier) { this.rsaVerifier = rsaVerifier; } @@ -33,12 +42,25 @@ public class AuthenticationHeadFilter extends OncePerRequestFilter { filterChain.doFilter(httpServletRequest, httpServletResponse); return; } - TokenUser user; try { Jwt jwt = JwtHelper.decodeAndVerify(token, rsaVerifier); String claims = jwt.getClaims(); user = JSON.parseObject(claims, TokenUser.class); + // 是否单点登录 + Long createTime = user.getCreateTime(); + Long tokenCreateTime = (Long) redisTemplate.opsForHash().get(GlobalUtil.LOGIN_USER_TOKEN, user.getUsername()); + if (!createTime.equals(tokenCreateTime)) { + httpServletResponse.setContentType("application/json;charset=UTF-8"); + httpServletResponse.getWriter().write("用户已在其他地方登录"); + return; + } + // 是否超时(默认1小时) + if (System.currentTimeMillis() > createTime + 1000 * 60 * 60) { + httpServletResponse.setContentType("application/json;charset=UTF-8"); + httpServletResponse.getWriter().write("Token已过期请重新登录"); + return; + } } catch (Exception e) { e.printStackTrace(); httpServletResponse.setContentType("application/json;charset=UTF-8"); diff --git a/src/main/java/com/objecteye/config/AuthenticationLoginFilter.java b/src/main/java/com/objecteye/config/AuthenticationLoginFilter.java index fb715ea..6d1d744 100644 --- a/src/main/java/com/objecteye/config/AuthenticationLoginFilter.java +++ b/src/main/java/com/objecteye/config/AuthenticationLoginFilter.java @@ -1,5 +1,6 @@ package com.objecteye.config; +import com.objecteye.pojo.AuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; diff --git a/src/main/java/com/objecteye/config/AuthenticationProviderConfig.java b/src/main/java/com/objecteye/config/AuthenticationProviderConfig.java index 2e6d6ba..2bafec4 100644 --- a/src/main/java/com/objecteye/config/AuthenticationProviderConfig.java +++ b/src/main/java/com/objecteye/config/AuthenticationProviderConfig.java @@ -1,5 +1,6 @@ package com.objecteye.config; +import com.objecteye.pojo.AuthenticationToken; import org.springframework.security.authentication.*; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; diff --git a/src/main/java/com/objecteye/config/AuthenticationToken.java b/src/main/java/com/objecteye/config/AuthenticationToken.java deleted file mode 100644 index 5ae9088..0000000 --- a/src/main/java/com/objecteye/config/AuthenticationToken.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.objecteye.config; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; - -import java.util.Collection; - -public class AuthenticationToken extends AbstractAuthenticationToken { - - private static final long serialVersionUID = 4169946299521307024L; - /** - * 用户名 - */ - private final Object principal; - /** - * 密码 - */ - private Object credentials; - - /** - * 创建一个认证成功的token - * - * @param principal - * @param credentials - * @param authorities - */ - public AuthenticationToken(Object principal, Object credentials, Collection authorities) { - super(authorities); - this.principal = principal; - this.credentials = credentials; - super.setAuthenticated(true); - } - - /** - * 创建一个未认证的token - * - * @param principal - * @param credentials - */ - public AuthenticationToken(Object principal, Object credentials) { - super(null); - this.principal = principal; - this.credentials = credentials; - super.setAuthenticated(false); - } - - @Override - public Object getCredentials() { - return this.credentials; - } - - @Override - public Object getPrincipal() { - return this.principal; - } -} diff --git a/src/main/java/com/objecteye/config/LoginFailureHandler.java b/src/main/java/com/objecteye/config/LoginFailureHandler.java deleted file mode 100644 index 012b9cb..0000000 --- a/src/main/java/com/objecteye/config/LoginFailureHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.objecteye.config; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 登录失败处理 - */ -public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler { - - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { - response.setContentType("application/json;charset=UTF-8"); - response.getWriter().write("登录失败"); - } -} diff --git a/src/main/java/com/objecteye/config/LoginSuccessHandler.java b/src/main/java/com/objecteye/config/LoginSuccessHandler.java deleted file mode 100644 index d423b05..0000000 --- a/src/main/java/com/objecteye/config/LoginSuccessHandler.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.objecteye.config; - -import com.alibaba.fastjson.JSON; -import org.springframework.security.core.Authentication; -import org.springframework.security.jwt.JwtHelper; -import org.springframework.security.jwt.crypto.sign.RsaSigner; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 登录成功处理 - */ -public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - - private RsaSigner signer; - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { - response.setContentType("application/json;charset=UTF-8"); - String userJsonStr = JSON.toJSONString(authentication.getPrincipal()); - String token = JwtHelper.encode(userJsonStr, signer).getEncoded(); - //签发token - response.getWriter().write("token=" + token); - } - - public void setSigner(RsaSigner signer) { - this.signer = signer; - } -} diff --git a/src/main/java/com/objecteye/config/WebSecurityConfig.java b/src/main/java/com/objecteye/config/WebSecurityConfig.java index 9e5e9da..d53b69c 100644 --- a/src/main/java/com/objecteye/config/WebSecurityConfig.java +++ b/src/main/java/com/objecteye/config/WebSecurityConfig.java @@ -1,10 +1,13 @@ package com.objecteye.config; import com.objecteye.common.ResultCode; +import com.objecteye.handle.LoginFailureHandler; +import com.objecteye.handle.LoginSuccessHandler; import com.objecteye.service.impl.UserDetailServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @@ -26,6 +29,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailServiceImpl userDetailService; + @Autowired + private RedisTemplate redisTemplate; + @Override protected void configure(HttpSecurity http) throws Exception { AuthenticationLoginFilter authenticationLoginFilter = new AuthenticationLoginFilter(); @@ -33,6 +39,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { LoginSuccessHandler loginSuccessHandler = new LoginSuccessHandler(); loginSuccessHandler.setSigner(signer); + loginSuccessHandler.setRedisTemplate(redisTemplate); authenticationLoginFilter.setAuthenticationSuccessHandler(loginSuccessHandler); authenticationLoginFilter.setAuthenticationFailureHandler(new LoginFailureHandler()); @@ -42,6 +49,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { AuthenticationHeadFilter headFilter = new AuthenticationHeadFilter(); headFilter.setRsaVerifier(verifier); + headFilter.setRedisTemplate(redisTemplate); http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> { response.setContentType("application/json;charset=UTF-8"); diff --git a/src/main/java/com/objecteye/controller/UserController.java b/src/main/java/com/objecteye/controller/UserController.java index f4d4087..598a8e8 100644 --- a/src/main/java/com/objecteye/controller/UserController.java +++ b/src/main/java/com/objecteye/controller/UserController.java @@ -4,6 +4,7 @@ import com.objecteye.common.CommonResult; import com.objecteye.service.UserServices; import com.objecteye.utils.GlobalUtil; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import java.util.Map; @@ -16,6 +17,11 @@ public class UserController extends BasicController { @Autowired public UserServices userServices; + @RequestMapping(value = "whoami", method = RequestMethod.POST, produces = GlobalUtil.COMMON_HEADER_CONTENT_TYPE) + public CommonResult whoAmI() { + return CommonResult.success(SecurityContextHolder.getContext().getAuthentication().getPrincipal()); + } + @RequestMapping(value = "checkUser", method = RequestMethod.POST, produces = GlobalUtil.COMMON_HEADER_CONTENT_TYPE) public CommonResult checkUser(@RequestBody Map requestMap) { return jsonObjectResultHandle(userServices.checkUser(requestMap)); diff --git a/src/main/java/com/objecteye/handle/LoginFailureHandler.java b/src/main/java/com/objecteye/handle/LoginFailureHandler.java new file mode 100644 index 0000000..e5d5b7e --- /dev/null +++ b/src/main/java/com/objecteye/handle/LoginFailureHandler.java @@ -0,0 +1,21 @@ +package com.objecteye.handle; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 登录失败处理 + */ +public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("登录失败"); + } +} diff --git a/src/main/java/com/objecteye/handle/LoginSuccessHandler.java b/src/main/java/com/objecteye/handle/LoginSuccessHandler.java new file mode 100644 index 0000000..af6f929 --- /dev/null +++ b/src/main/java/com/objecteye/handle/LoginSuccessHandler.java @@ -0,0 +1,44 @@ +package com.objecteye.handle; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.objecteye.utils.GlobalUtil; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.core.Authentication; +import org.springframework.security.jwt.JwtHelper; +import org.springframework.security.jwt.crypto.sign.RsaSigner; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 登录成功处理 + */ +public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private RsaSigner signer; + + private RedisTemplate redisTemplate; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { + response.setContentType("application/json;charset=UTF-8"); + String userJsonStr = JSON.toJSONString(authentication.getPrincipal()); + JSONObject userJson = JSON.parseObject(userJsonStr); + // 保存登录存根 + redisTemplate.opsForHash().put(GlobalUtil.LOGIN_USER_TOKEN, userJson.getString("username"), userJson.getLongValue("createTime")); + String token = JwtHelper.encode(userJsonStr, signer).getEncoded(); + //签发token + response.getWriter().write("token=" + token); + } + + public void setSigner(RsaSigner signer) { + this.signer = signer; + } + + public void setRedisTemplate(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } +} diff --git a/src/main/java/com/objecteye/pojo/AuthenticationToken.java b/src/main/java/com/objecteye/pojo/AuthenticationToken.java new file mode 100644 index 0000000..8f8c7b9 --- /dev/null +++ b/src/main/java/com/objecteye/pojo/AuthenticationToken.java @@ -0,0 +1,56 @@ +package com.objecteye.pojo; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +import java.util.Collection; + +public class AuthenticationToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = 4169946299521307024L; + /** + * 用户名 + */ + private final Object principal; + /** + * 密码 + */ + private Object credentials; + + /** + * 创建一个认证成功的token + * + * @param principal + * @param credentials + * @param authorities + */ + public AuthenticationToken(Object principal, Object credentials, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + /** + * 创建一个未认证的token + * + * @param principal + * @param credentials + */ + public AuthenticationToken(Object principal, Object credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(false); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } +} diff --git a/src/main/java/com/objecteye/pojo/TokenUser.java b/src/main/java/com/objecteye/pojo/TokenUser.java index c566ff5..f2fc46b 100644 --- a/src/main/java/com/objecteye/pojo/TokenUser.java +++ b/src/main/java/com/objecteye/pojo/TokenUser.java @@ -17,11 +17,14 @@ public class TokenUser implements UserDetails { private String password; + private Long createTime; + private List simpleGrantedAuthorities; public TokenUser(String userName, String password, String... roles) { this.userName = userName; this.password = password; + this.createTime = System.currentTimeMillis(); this.simpleGrantedAuthorities = Arrays.stream(roles).map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } @@ -74,4 +77,12 @@ public class TokenUser implements UserDetails { public void setSimpleGrantedAuthorities(List simpleGrantedAuthorities) { this.simpleGrantedAuthorities = simpleGrantedAuthorities; } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } } diff --git a/src/main/java/com/objecteye/pojo/UserGroup.java b/src/main/java/com/objecteye/pojo/UserGroup.java index ddcf16c..884d36f 100644 --- a/src/main/java/com/objecteye/pojo/UserGroup.java +++ b/src/main/java/com/objecteye/pojo/UserGroup.java @@ -25,7 +25,7 @@ public class UserGroup implements Serializable { private String groupLevel; /** - * 父级组织id(根为-1, 备用) + * 父级组织id(根为-1) */ private String parentCode; diff --git a/src/main/java/com/objecteye/service/impl/AccessConfirmServiceImpl.java b/src/main/java/com/objecteye/service/impl/AccessConfirmServiceImpl.java new file mode 100644 index 0000000..077c7cb --- /dev/null +++ b/src/main/java/com/objecteye/service/impl/AccessConfirmServiceImpl.java @@ -0,0 +1,92 @@ +package com.objecteye.service.impl; + +import com.objecteye.pojo.SpecialAuthenticationUrlConfig; +import com.objecteye.pojo.UserDetailsMsg; +import com.objecteye.pojo.UserGroup; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component("accessConfirmService") +public class AccessConfirmServiceImpl { + + @Autowired + private MongoTemplate mongoTemplate; + + private AntPathMatcher antPathMatcher = new AntPathMatcher(); + + public boolean hasPermission(HttpServletRequest request, Authentication auth) { + // 不需要权限的接口 + List permitAll = new ArrayList<>(); + permitAll.add("/login"); + permitAll.add("/vehicle/user/addUser"); + + String requestUri = request.getRequestURI(); + if (permitAll.contains(requestUri)) { + return true; + } + + // 匿名token不允许访问所有的接口 + if (auth instanceof AnonymousAuthenticationToken) { + return false; + } + + UserDetails user = (UserDetails) auth.getPrincipal(); + Map specialUrlAccessMap = queryUrlByUserName(user.getUsername()); + for (Map.Entry entry : specialUrlAccessMap.entrySet()) { + if (antPathMatcher.match(entry.getKey(), requestUri)) { + return entry.getValue(); + } + } + return true; + } + + /** + * 查询用户权限 + * + * @param userName 用户名 + * @return key: 需要权限的url; value: 是否可以访问 + */ + private Map queryUrlByUserName(String userName) { + List userDetailsMsgList = mongoTemplate.find(Query.query(Criteria.where("userName").is(userName)), UserDetailsMsg.class); + Map specialUrlLevelMap = new HashMap<>(); + if (userDetailsMsgList.size() > 0) { + List levelList = new ArrayList<>(); + UserDetailsMsg userDetailsMsg = userDetailsMsgList.get(0); + levelList.add(userDetailsMsg.getUserRole()); + List userGroups = mongoTemplate.find(Query.query(Criteria.where("grouoId").is(userDetailsMsg.getGroup())), UserGroup.class); + if (userGroups.size() > 0) { + levelList.add(userGroups.get(0).getGroupLevel()); + } + // 保存的是所有的需要特殊权限才能访问的 + List specialUrlList = mongoTemplate.find(new Query(), SpecialAuthenticationUrlConfig.class); + if (specialUrlList.size() > 0) { + for (SpecialAuthenticationUrlConfig specialUrlConfig : specialUrlList) { + String url = specialUrlConfig.getUrl(); + Integer level = specialUrlConfig.getLevel(); + if (specialUrlLevelMap.containsKey(url)) { + // 历史数据不允许访问, 当前数据允许访问则刷新是否可以访问的状态 + if (!specialUrlLevelMap.get(url) && levelList.contains(level)) { + specialUrlLevelMap.put(url, true); + } + } else { + specialUrlLevelMap.put(url, levelList.contains(level)); + } + } + } + } + return specialUrlLevelMap; + } +} diff --git a/src/main/java/com/objecteye/service/impl/UserDetailServiceImpl.java b/src/main/java/com/objecteye/service/impl/UserDetailServiceImpl.java index dc6b29c..b10bd19 100644 --- a/src/main/java/com/objecteye/service/impl/UserDetailServiceImpl.java +++ b/src/main/java/com/objecteye/service/impl/UserDetailServiceImpl.java @@ -2,6 +2,7 @@ package com.objecteye.service.impl; import com.objecteye.pojo.TokenUser; import com.objecteye.pojo.UserDetailsMsg; +import com.objecteye.pojo.UserGroup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; @@ -12,8 +13,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; -import java.util.List; - @Component public class UserDetailServiceImpl implements UserDetailsService { @@ -29,19 +28,19 @@ public class UserDetailServiceImpl implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { - List userDetailsMsgs = mongoTemplate.find(Query.query(Criteria.where("userName").is(s)), UserDetailsMsg.class); - - // admin - UserDetailsMsg superAdminUser = new UserDetailsMsg(); - superAdminUser.setUsername("superAdmin"); - superAdminUser.setPassword("123456"); - superAdminUser.setUserRole("1"); - userDetailsMsgs.add(superAdminUser); - if (userDetailsMsgs.size() > 0) { - UserDetailsMsg userDetailsMsg = userDetailsMsgs.get(0); - return new TokenUser(userDetailsMsg.getUsername(), passwordEncoder.encode(userDetailsMsg.getPassword())); + if ("superAdmin".equals(s)) { + return new TokenUser("superAdmin", passwordEncoder.encode("123456"), "1"); + } + UserDetailsMsg userDetailsMsg = mongoTemplate.findOne(Query.query(Criteria.where("username").is(s)), UserDetailsMsg.class); + if (userDetailsMsg != null) { + UserGroup userGroup = mongoTemplate.findOne(Query.query(Criteria.where("groupCode").is(userDetailsMsg.getGroup())), UserGroup.class); + String userRole = userDetailsMsg.getUserRole(); + if (userGroup != null) { + String groupLevel = userGroup.getGroupLevel(); + userRole = String.valueOf(Math.min(Integer.parseInt(userRole), Integer.parseInt(groupLevel))); + } + return new TokenUser(userDetailsMsg.getUsername(), passwordEncoder.encode(userDetailsMsg.getPassword()), userRole); } - return null; } } diff --git a/src/main/java/com/objecteye/service/impl/UserGroupServiceImpl.java b/src/main/java/com/objecteye/service/impl/UserGroupServiceImpl.java index 707a5a0..bcec611 100644 --- a/src/main/java/com/objecteye/service/impl/UserGroupServiceImpl.java +++ b/src/main/java/com/objecteye/service/impl/UserGroupServiceImpl.java @@ -66,7 +66,14 @@ public class UserGroupServiceImpl implements IUserGroupService { @Override public JSONObject addGroup(Map requestMap) { UserGroup userGroup = JSON.parseObject(JSON.toJSONString(requestMap), UserGroup.class); - UserGroup lastMaxCodeGroup = mongoTemplate.findOne(new Query().with(Sort.by(Sort.Order.desc("groupCode"))), UserGroup.class); + // 默认是根组织 + String parentCode = "-1"; + if (userGroup.getParentCode() != null && !"".equals(userGroup.getParentCode())) { + parentCode = userGroup.getParentCode(); + } + UserGroup lastMaxCodeGroup = mongoTemplate + .findOne(new Query(Criteria.where("parentCode").is(parentCode)) + .with(Sort.by(Sort.Order.desc("groupCode"))).limit(1), UserGroup.class); if (lastMaxCodeGroup == null) { userGroup.setGroupCode("001"); userGroup.setParentCode("-1"); @@ -81,7 +88,6 @@ public class UserGroupServiceImpl implements IUserGroupService { } else { resultObj.put("error", "创建失败"); } - return resultObj; } diff --git a/src/main/java/com/objecteye/utils/GlobalUtil.java b/src/main/java/com/objecteye/utils/GlobalUtil.java index d8c2a86..156aba2 100644 --- a/src/main/java/com/objecteye/utils/GlobalUtil.java +++ b/src/main/java/com/objecteye/utils/GlobalUtil.java @@ -35,6 +35,10 @@ public class GlobalUtil { public final static String PREVIEWIPLISTLIST = "previewIpList"; public final static String ALARMMSG = "alarmMsg"; public final static String DEPLOYIDANDENDTIME = "deployIdAndTime"; + /** + * 已经登录的用户token相关信息, hashKey = loginUserToken, key: username, value: login time(long type) + */ + public final static String LOGIN_USER_TOKEN = "loginUserToken"; public final static String COMMON_HEADER_CONTENT_TYPE = "application/json;charset=UTF-8"; -- libgit2 0.21.4