注解:
1 import java.lang.annotation.*; 2 3 /** 4 * 5 * 注解在controller方法上 6 * 表示可以使用代理人这个功能的接口 7 */ 8 9 @Inherited 10 @Retention(RetentionPolicy.RUNTIME) 11 @Target(ElementType.METHOD) 12 public @interface CanProxy { 13 }
拦截器处理注解:
1 import com.nd.gaea.rest.security.authens.UserInfo; 2 import nd.sdp.idea.base.annotation.CanProxy; 3 import nd.sdp.idea.base.support.ContextHolder; 4 import nd.sdp.idea.exception.BizException; 5 import nd.sdp.idea.exception.ErrorCode; 6 import nd.sdp.idea.modules.proxy.entity.Proxy; 7 import nd.sdp.idea.modules.proxy.service.ProxyService; 8 import org.apache.commons.lang3.StringUtils; 9 import org.slf4j.Logger; 10 import org.slf4j.LoggerFactory; 11 import org.springframework.security.core.Authentication; 12 import org.springframework.security.core.context.SecurityContextHolder; 13 import org.springframework.web.method.HandlerMethod; 14 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 15 16 import javax.servlet.http.HttpServletRequest; 17 import javax.servlet.http.HttpServletResponse; 18 19 /** 20 * 代理人身份解析验证拦截器 21 * @author yanguanyu(290536) 22 * @since 0.1 created on 2016/10/18. 23 */ 24 public class ProxyResolveInterceptor extends HandlerInterceptorAdapter { 25 26 private static final Logger logger = LoggerFactory.getLogger(ProxyResolveInterceptor.class); 27 28 private ContextHolder context = ContextHolder.getBean(ContextHolder.class); 29 private ProxyService proxyService = ContextHolder.getBean(ProxyService.class); 30 31 @Override 32 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 33 34 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 35 if (authentication == null || "anonymousUser".equals(authentication.getPrincipal())) { 36 return true; 37 } 38 UserInfo userInfo = (UserInfo) authentication.getPrincipal(); 39 context.setUserInfo(userInfo); 40 41 if (canProxy(handler)) { 42 String principalId = request.getHeader("principal"); 43 Proxy proxy = proxyService.canProxyFor(context.getUserId(), principalId); 44 if (proxy != null) { // 代理人存在 设置代理人信息 45 context.setPrincipalId(proxy.getUserId()); 46 context.setPrincipalUserName(proxy.getUserName()); 47 } else if(StringUtils.isEmpty(principalId)) { // 请求代理人信息为空 代理人信息设置为登录人信息 48 context.setPrincipalId(context.getUserId()); 49 context.setPrincipalUserName(context.getUserName()); 50 } else { 51 throw new BizException(ErrorCode.PROXY_ACCESS_DENIED, String.format("没有代理用户%s的权限", principalId)); 52 } 53 } 54 else { // 没有注解 代理人信息设置为登录人信息 55 context.setPrincipalId(context.getUserId()); 56 context.setPrincipalUserName(context.getUserName()); 57 } 58 59 return super.preHandle(request, response, handler); 60 } 61 // 验证目标方法是否有该注解 62 private boolean canProxy(Object handler) { 63 if (! (handler instanceof HandlerMethod)) return false; 64 CanProxy annotationOnMethod = ((HandlerMethod) handler).getMethodAnnotation(CanProxy.class); 65 return annotationOnMethod != null; 66 } 67 68 }
上下文:
1 import com.nd.gaea.rest.security.authens.UserInfo; 2 import org.springframework.beans.BeansException; 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.ApplicationContextAware; 5 import org.springframework.stereotype.Component; 6 import org.springframework.web.context.request.RequestContextHolder; 7 import org.springframework.web.context.request.ServletRequestAttributes; 8 9 import javax.servlet.http.HttpServletRequest; 10 11 /** 12 * 借助RequestContextHolder来保存请求中的身份等上下文信息<br/> 13 * @author yanguanyu(290536) 14 * @since 0.1 created on 2016/10/18. 15 */ 16 @Component 17 public class ContextHolder implements ApplicationContextAware { 18 19 private static ApplicationContext applicationContext; 20 21 private final static String KEY_USER_INFO = "user_info"; //当前用户信息 22 private final static String KEY_PRINCIPAL_ID = "principal_id"; //委托人(被代理人)用户id 23 private final static String KEY_PRINCIPAL_USER_NAME = "principal_user_name"; //委托人(被代理人)用户名称 24 25 private ContextHolder(){} 26 27 @Override 28 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 29 initContextHolder(applicationContext); 30 } 31 32 private static void initContextHolder(ApplicationContext context) { 33 ContextHolder.applicationContext = context; 34 } 35 36 public static ApplicationContext getApplicatinContext() { 37 return applicationContext; 38 } 39 40 // 获取与当前线程绑定的HttpServletRequest对象 41 public HttpServletRequest getRequest() { 42 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 43 return attributes.getRequest(); 44 } 45 46 public static Object getBean(String name) { 47 return applicationContext.getBean(name); 48 } 49 50 public static <T> T getBean(String name, Class<T> requiredType) { 51 return applicationContext.getBean(name, requiredType); 52 } 53 54 public static <T> T getBean(Class<T> requiredType) { 55 return applicationContext.getBean(requiredType); 56 } 57 58 public void setUserInfo(UserInfo userInfo) { 59 getRequest().setAttribute(KEY_USER_INFO, userInfo); 60 } 61 62 public UserInfo getUserInfo() { 63 return (UserInfo) getRequest().getAttribute(KEY_USER_INFO); 64 } 65 66 public String getUserId() { 67 return (String) getUserInfo().getUserId(); 68 } 69 70 public String getUserName() { 71 return (String) getUserInfo().getOrgExinfo().get("real_name"); 72 } 73 74 //设置委托人用户id,如果没有使用代理人功能,这个值与getUserId()相同 75 public void setPrincipalId(String principalId) { 76 getRequest().setAttribute(KEY_PRINCIPAL_ID, principalId); 77 } 78 79 public String getPrincipalId() { 80 return (String) getRequest().getAttribute(KEY_PRINCIPAL_ID); 81 } 82 83 //设置委托人用户名称,如果没有使用代理人功能,这个值与getUserName()相同 84 public void setPrincipalUserName(String principalUserName) { 85 getRequest().setAttribute(KEY_PRINCIPAL_USER_NAME, principalUserName); 86 } 87 88 public String getPrincipalUserName() { 89 return (String) getRequest().getAttribute(KEY_PRINCIPAL_USER_NAME); 90 } 91 }