diff --git a/parent/core.sdk/src/main/java/com/lyms/annotation/TokenRequired.java b/parent/core.sdk/src/main/java/com/lyms/annotation/TokenRequired.java new file mode 100644 index 0000000..289f8d1 --- /dev/null +++ b/parent/core.sdk/src/main/java/com/lyms/annotation/TokenRequired.java @@ -0,0 +1,16 @@ +package com.lyms.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by Administrator on 2015/9/25 0025. + */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface TokenRequired +{ +} diff --git a/parent/core.sdk/src/main/java/com/lyms/constants/Constants.java b/parent/core.sdk/src/main/java/com/lyms/constants/Constants.java index cc5d1e3..7231d8e 100644 --- a/parent/core.sdk/src/main/java/com/lyms/constants/Constants.java +++ b/parent/core.sdk/src/main/java/com/lyms/constants/Constants.java @@ -13,4 +13,6 @@ public interface Constants { public static final String CAPTCHA_TOKEN = "captcha_token"; public static final String CAPTCHA_FIELDNAME = "captcha"; public static final String CAPTCHA_CACHE = "captcha_cache"; + + String AUTH_HEADER="Authorization"; } diff --git a/parent/core.sdk/src/main/java/com/lyms/context/ContextHolder.java b/parent/core.sdk/src/main/java/com/lyms/context/ContextHolder.java new file mode 100644 index 0000000..ff63a25 --- /dev/null +++ b/parent/core.sdk/src/main/java/com/lyms/context/ContextHolder.java @@ -0,0 +1,32 @@ +package com.lyms.context; + + + +/** + * 上下文持有 + * + * Created by Administrator on 2015/9/25 0025. + */ +public class ContextHolder +{ + + private static final ThreadLocal contextHolder =new ThreadLocal(); + + public static PlatformContext getContext (){ + PlatformContext context = contextHolder.get(); + if(null==context){ + throw new UnsupportedOperationException("请配置TokenRequired注解."); + } + return context; + } + + public static void setContext(PlatformContext context){ + if(null == context){ + throw new NullPointerException("context must not null."); + } + contextHolder.set(context); + } + public static void clean(){ + contextHolder.remove(); + } +} diff --git a/parent/core.sdk/src/main/java/com/lyms/context/PlatformContext.java b/parent/core.sdk/src/main/java/com/lyms/context/PlatformContext.java new file mode 100644 index 0000000..fbadc42 --- /dev/null +++ b/parent/core.sdk/src/main/java/com/lyms/context/PlatformContext.java @@ -0,0 +1,52 @@ +package com.lyms.context; + + +/** + * + * + * Created by Administrator on 2015/9/25 0025. + */ +public class PlatformContext +{ + + private String token; + + private String userId; + + private String ipAddr; + //当前登录人所在的医院id + private String hospitalId; + + public String getHospitalId() + { + return hospitalId; + } + + public void setHospitalId(String hospitalId) + { + this.hospitalId = hospitalId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } +} \ No newline at end of file diff --git a/parent/core.sdk/src/main/java/com/lyms/util/IpUtils.java b/parent/core.sdk/src/main/java/com/lyms/util/IpUtils.java new file mode 100644 index 0000000..ec6be24 --- /dev/null +++ b/parent/core.sdk/src/main/java/com/lyms/util/IpUtils.java @@ -0,0 +1,65 @@ +package com.lyms.util; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 添加类的一句话简单描述。 + *

+ * 详细描述 + *

+ * 示例代码 + *

+ * 
+ * + * @author JIAZHI.JIANG + * @version BME V100R001 2017-04-10 14:22 + * @since BME V100R001C40B104 + */ +public class IpUtils +{ + + + /** + *
  • @Description:获取客户端IP + *
  • @param request + *
  • @return + *
  • 创建人:方承 + *
  • 创建时间:2016年11月26日 + *
  • 修改人: + *
  • 修改时间: + */ + public static final String getHost(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (StrUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StrUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StrUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + if (StrUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + if ("127.0.0.1".equals(ip)) { + InetAddress inet = null; + try { // 根据网卡取本机配置的IP + inet = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + ip = inet.getHostAddress(); + } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ip != null && ip.length() > 15) { + if (ip.indexOf(",") > 0) { + ip = ip.substring(0, ip.indexOf(",")); + } + } + return ip; + } + +} diff --git a/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/TokenService.java b/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/TokenService.java index 7ab36f6..674cb6c 100644 --- a/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/TokenService.java +++ b/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/TokenService.java @@ -7,9 +7,9 @@ public interface TokenService { - String createToken(Integer userId); + String createToken(String userId); - String createToken(Integer userId, Integer second); + String createToken(String userId, Integer second); boolean resetToken(String token); @@ -17,11 +17,11 @@ public interface TokenService boolean validToken(String token, Integer second); - Integer getUserId(String token); + String getUserId(String token); - void deleteAllToken(Integer userId); + void deleteAllToken(String userId); - void deleteAllToken(Integer userId, String prefix); + void deleteAllToken(String userId, String prefix); void deleteToken(String token); diff --git a/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/impl/TokenServiceImpl.java b/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/impl/TokenServiceImpl.java index c18549c..af2a2aa 100644 --- a/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/impl/TokenServiceImpl.java +++ b/parent/hospital.mac/src/main/java/com/lyms/hospital/service/token/impl/TokenServiceImpl.java @@ -47,7 +47,7 @@ public class TokenServiceImpl implements TokenService } @Override - public String createToken(Integer userId, Integer second) + public String createToken(String userId, Integer second) { String token = getPrefix() + TokenUtils.getToken(UUID.randomUUID().toString()); @@ -75,7 +75,7 @@ public class TokenServiceImpl implements TokenService } @Override - public String createToken(Integer userId) + public String createToken(String userId) { return createToken(userId, seconds); } @@ -111,13 +111,13 @@ public class TokenServiceImpl implements TokenService } @Override - public Integer getUserId(String token) + public String getUserId(String token) { Object obj = redisTemplate.opsForValue().get(token); if (obj != null) { redisTemplate.opsForValue().set(token, SerializeUtils.serialize(obj), getSeconds()); - return (Integer) obj; + return (String) obj; } return null; } @@ -129,7 +129,7 @@ public class TokenServiceImpl implements TokenService } @Override - public void deleteAllToken(Integer userId) + public void deleteAllToken(String userId) { String tempKey = getPrefix() + "_tokenlist_" + userId; Object obj = redisTemplate.opsForValue().get(tempKey); @@ -142,7 +142,7 @@ public class TokenServiceImpl implements TokenService } @Override - public void deleteAllToken(Integer userId, String prefix) + public void deleteAllToken(String userId, String prefix) { String tempKey = prefix + "_tokenlist_" + userId; Object obj = redisTemplate.opsForValue().get(tempKey); diff --git a/parent/hospital.web/src/main/java/com/lyms/hospital/inteceptor/TokenValidateInteceptor.java b/parent/hospital.web/src/main/java/com/lyms/hospital/inteceptor/TokenValidateInteceptor.java new file mode 100644 index 0000000..889cb14 --- /dev/null +++ b/parent/hospital.web/src/main/java/com/lyms/hospital/inteceptor/TokenValidateInteceptor.java @@ -0,0 +1,78 @@ +package com.lyms.hospital.inteceptor; + + +import com.lyms.annotation.TokenRequired; +import com.lyms.constants.Constants; +import com.lyms.context.ContextHolder; +import com.lyms.exception.LoginException; +import com.lyms.hospital.session.SessionProvider; +import com.lyms.web.controller.BaseController; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.security.auth.login.LoginContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.annotation.Annotation; + +/** + * 验证token拦截器 + *

    + *

      + *
    • + * 1、springmvc中配置TokenValidateInteceptor的拦截 + * 2、在需要拦截的方法上面配置TokenRequired注解 + *
    • + *
    + */ +public class TokenValidateInteceptor extends HandlerInterceptorAdapter +{ + + @Autowired + private SessionProvider sessionProvider; + + public static boolean isSiteController(Object handler) { + return handler instanceof HandlerMethod && (((HandlerMethod) handler).getBean() instanceof BaseController); + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + if (!isSiteController(handler)) + return true; + TokenRequired clientRequired = findAnnotation((HandlerMethod) handler, TokenRequired.class); + if (null == clientRequired) + return true; + + return validateToken(request, response); + } + + private T findAnnotation(HandlerMethod handler, Class annotationType) { + T annotation = handler.getBeanType().getAnnotation(annotationType); + if (annotation != null) + return annotation; + return handler.getMethodAnnotation(annotationType); + } + + public boolean validateToken(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { + String token = httpServletRequest.getHeader(Constants.AUTH_HEADER); + if (StringUtils.isEmpty(token)) { + throw new LoginException("miss auth."); + } + LoginContext loginContext = sessionProvider.checkSession(httpServletRequest, httpServletResponse, token); + + return true; + } + + /** + * This implementation is empty. + */ + @Override + public void afterCompletion( + HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) + throws Exception { + ContextHolder.clean(); + } +} \ No newline at end of file diff --git a/parent/hospital.web/src/main/java/com/lyms/hospital/session/ISessionProvider.java b/parent/hospital.web/src/main/java/com/lyms/hospital/session/ISessionProvider.java new file mode 100644 index 0000000..8bec0c7 --- /dev/null +++ b/parent/hospital.web/src/main/java/com/lyms/hospital/session/ISessionProvider.java @@ -0,0 +1,32 @@ +package com.lyms.hospital.session; + +import javax.security.auth.login.LoginContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * 提供验证session的方法 + * + * Created by Administrator on 2016/6/2 0002. + */ +public interface ISessionProvider +{ + + /** + * 检查session + * + * @param request + * @param response + * @param token + * @return + */ + boolean checkSession(HttpServletRequest request, HttpServletResponse response, String token); + + /** + * 删除session + * @param token + */ + void removeSession(String token); + +} diff --git a/parent/hospital.web/src/main/java/com/lyms/hospital/session/SessionProvider.java b/parent/hospital.web/src/main/java/com/lyms/hospital/session/SessionProvider.java new file mode 100644 index 0000000..ba9dcc5 --- /dev/null +++ b/parent/hospital.web/src/main/java/com/lyms/hospital/session/SessionProvider.java @@ -0,0 +1,75 @@ +package com.lyms.hospital.session; + + +import javax.security.auth.login.LoginContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * session 能力提供 + *

    + *

    + * Created by Administrator on 2016/6/2 0002. + */ +public class SessionProvider implements ISessionProvider { + /** + * 配置 + */ + private Map iSessionProviderMap; + /** + * 默认的session提供 + */ + private ISessionProvider defaultSessionProvider; + /** + * 当前策略 + */ + private String currentStrateger; + + public String getCurrentStrateger() { + return currentStrateger; + } + + public void setCurrentStrateger(String currentStrateger) { + this.currentStrateger = currentStrateger; + } + + public ISessionProvider getDefaultSessionProvider() { + return defaultSessionProvider; + } + + public void setDefaultSessionProvider(ISessionProvider defaultSessionProvider) { + this.defaultSessionProvider = defaultSessionProvider; + } + + public Map getiSessionProviderMap() { + return iSessionProviderMap; + } + + public void setiSessionProviderMap(Map iSessionProviderMap) { + this.iSessionProviderMap = iSessionProviderMap; + } + + @Override + public LoginContext checkSession(HttpServletRequest request, HttpServletResponse response, String token) { + ISessionProvider iSessionProvider = iSessionProviderMap.get(currentStrateger); + if (null != iSessionProvider) { + return iSessionProvider.checkSession(request, response, token); + } + if (null != defaultSessionProvider) { + return defaultSessionProvider.checkSession(request, response, token); + } + return null; + } + + @Override + public void removeSession(String token) { + ISessionProvider iSessionProvider = iSessionProviderMap.get(currentStrateger); + if (null != iSessionProvider) { + iSessionProvider.removeSession(token); + } + if (null != defaultSessionProvider) { + defaultSessionProvider.removeSession(token); + } + } +} \ No newline at end of file diff --git a/parent/hospital.web/src/main/java/com/lyms/hospital/session/strategy/LocalRedisSessionStrategy.java b/parent/hospital.web/src/main/java/com/lyms/hospital/session/strategy/LocalRedisSessionStrategy.java new file mode 100644 index 0000000..829ab77 --- /dev/null +++ b/parent/hospital.web/src/main/java/com/lyms/hospital/session/strategy/LocalRedisSessionStrategy.java @@ -0,0 +1,79 @@ +package com.lyms.hospital.session.strategy; + +import com.lyms.base.common.entity.user.Users; +import com.lyms.base.common.service.user.UsersService; +import com.lyms.context.ContextHolder; +import com.lyms.context.PlatformContext; +import com.lyms.exception.LoginException; +import com.lyms.hospital.service.token.TokenService; +import com.lyms.hospital.session.ISessionProvider; +import com.lyms.util.IpUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * redis session 管理策越。 + *

    + * 详细描述 + *

    + * 示例代码 + *

    + * 
    + * + * @author JIAZHI.JIANG + * @version BME V100R001 2017-04-10 11:14 + * @since BME V100R001C40B104 + */ +@Component +public class LocalRedisSessionStrategy implements ISessionProvider +{ + + //日志调测器 + private static final Logger logger = LoggerFactory.getLogger(LocalRedisSessionStrategy.class); + + @Autowired + private TokenService tokenService; + @Autowired + private UsersService userService; + + @Override + public boolean checkSession(HttpServletRequest request, HttpServletResponse response, String token) + { + if (StringUtils.isEmpty(token)) + { + throw new LoginException(""); + } + String userId = tokenService.getUserId(token); + + if (StringUtils.isEmpty(userId)) + { + throw new LoginException(""); + } + + PlatformContext context = new PlatformContext(); + context.setToken(token); + context.setUserId(userId); + context.setIpAddr(IpUtils.getHost(request)); + + Users localUserService = userService.selectById(userId); + if (null == localUserService) + { + throw new LoginException(""); + } + context.setHospitalId(localUserService.getOrgId()); + ContextHolder.setContext(context); + return true; + } + + @Override + public void removeSession(String token) + { + tokenService.deleteToken(token); + } +}