注解:
1 import java.lang.annotation.*; 2 3 /** 4 * 5 * 注解在controller方法上 6 * 表示可以使用代理人这个功能的接口 7 */ 8 9 @Inherited10 @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 @Override32 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来保存请求中的身份等上下文信息13 * @author yanguanyu(290536)14 * @since 0.1 created on 2016/10/18.15 */16 @Component17 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"; //委托人(被代理人)用户id23 private final static String KEY_PRINCIPAL_USER_NAME = "principal_user_name"; //委托人(被代理人)用户名称24 25 private ContextHolder(){}26 27 @Override28 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 staticT getBean(String name, Class requiredType) {51 return applicationContext.getBean(name, requiredType);52 }53 54 public static T getBean(Class 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 }