BeanNameAutoProxy1

通过配置的方式为bean自动创建拦截器,代码简例:

AppConfig:
import org.aopalliance.aop.Advice;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by ysma on 2016/8/16.
 */
@Configuration
public class AppConfig {
    //要创建代理的目标Bean
    @Bean
    public UserService userService(){
        return new UserServiceImpl();
    }
    //创建Advice或Advisor
    @Bean
    public Advice myMethodInterceptor(){
        return new MyMethodInterceptor();
    }
    //使用BeanNameAutoProxyCreator来创建代理
    @Bean
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator(){
        BeanNameAutoProxyCreator beanNameAutoProxyCreator=new BeanNameAutoProxyCreator();
        //设置要创建代理的那些Bean的名字
        beanNameAutoProxyCreator.setBeanNames(new String[]{"userSer*"});
        //设置拦截链名字(这些拦截器是有先后顺序的)
        beanNameAutoProxyCreator.setInterceptorNames(new String[]{"myMethodInterceptor"});
        beanNameAutoProxyCreator.setOptimize(true);
        return beanNameAutoProxyCreator;
    }
}

 

main:

public class main {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService= applicationContext.getBean(UserService.class);
        userService.print();
    }
}

MyMethodInterceptor:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * Created by ysma on 2016/8/16.
 */
public class MyMethodInterceptor  implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println(getClass()+"调用方法前");
        Object ret=invocation.proceed();
        System.out.println(getClass()+"调用方法后");
        return ret;
    }

}

userservice:

/**
 * Created by ysma on 2016/8/16.
 */
public interface UserService {
    void print();
}

userserviceImpl:

public class UserServiceImpl implements UserService {
    public void print(){
        //System.out.println(getClass()+"#print");
    }
}

===================分割线=============================

1、spring注解切面和控制器

@Component
@Order(3)
public class AuthUtil extends BeanNameAutoProxyCreator implements InitializingBean{

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthUtil.class);


    @Override
    public void afterPropertiesSet() throws Exception {
        super.setBeanNames(new String[]{"XXXXController"});
        super.setInterceptorNames(new String[]{"asrAuthInterceptor"});
        super.setOptimize(true);
        LOGGER.info("start config interceptor:{} for {}", "asrAuthInterceptor", "silkRoadController");
    }
}

2、切面编码

/**
 * @author ysma
 * @since  2016/9/9
 */
@Component
public class AsrAuthInterceptor implements MethodBeforeAdvice {

    private static final Logger LOGGER = LoggerFactory.getLogger(AsrAuthInterceptor.class);

    /**按分钟统计鉴权总数*/
    private static final String AUTHTOTAL = "ATD:ASR:AUTH:TOTAL:COUNT";

    /**按分钟统计鉴权失败总数*/
    private static final String AUTHFAIL = "ATD:ASR:AUTH:FAIL:COUNT";

    private static final long SECONDS = 4*60*60;

    @Resource
    ThreadPoolTaskExecutor aspectExecutor;

    @Resource
    ConfigApi configApi;

    @Resource
    UserDAO userDAO;

    @Resource
    private RedisManager redisManager;

    /**
     *
     * @param method method being invoked
     * @param args arguments to the method
     * @param target target of the method invocation. May be {@code null}.
     * @throws Throwable if this object wishes to abort the call.
     * Any exception thrown will be returned to the caller if it's
     * allowed by the method signature. Otherwise the exception
     * will be wrapped as a runtime exception.
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        ApiAuth apiAuth = method.getAnnotation(ApiAuth.class);
        //鉴权开关
        String authIt = configApi.get("authIt");
        if(apiAuth != null && "true".equals(authIt)){
            LOGGER.debug("[AuthInterceptor] 对{}的方法{}进行鉴权", target.getClass().getSimpleName(), method.getName());
            countAuth(AUTHTOTAL);
            //获取报文,获取签名,获取供应商id/采购商id
            Map<String, String> paramMap = getParamFromArgs(args);
            String vendorId = paramMap.get("vendorId");

            User user = userDAO.queryUserById(vendorId);
            String publicKey = user.getPublicKey();
            String privateKey = user.getPrivateKey();
            if(publicKey == null || privateKey == null){
                LOGGER.error("[AuthInterceptor] 供应商Id:{}鉴权失败,原因:密钥缺失", vendorId);
                countAuth(AUTHFAIL);
                throw new ATDException("密钥缺失", ErrorCode.KEY_MISS);
            } else {
                try {
                    boolean flag = RsaCrypt.verify(publicKey, privateKey, paramMap.get("message"), paramMap.get("sign"));
                    if(!flag){
                        LOGGER.error("[AuthInterceptor] 供应商Id:{}鉴权失败,原因:报文不一致", vendorId);
                        countAuth(AUTHFAIL);
                        throw new ATDException("报文不一致", ErrorCode.MESSAGE_DIFFERENCE);
                    }
                } catch (Exception e) {
                    LOGGER.error("[AuthInterceptor] 校验失败:{}", e.getMessage());
                    countAuth(AUTHFAIL);
                    throw new ATDException("校验失败", ErrorCode.MESSAGE_DIFFERENCE);
                }
            }
        } else {
            LOGGER.debug("[AuthInterceptor] {}不需要鉴权", target.getClass().getSimpleName());
        }
    }

    /**
     * @param args param
     * @throws ATDException
     */
    private Map<String, String> getParamFromArgs(Object[] args) throws ATDException {
        Map<String, String> paramMap = new HashMap<String, String>();
        //1.get request
        HttpServletRequest request = getRequest(args);
        if(request == null){
            LOGGER.warn("[AuthInterceptor], 未获取到request参数,请在controller入参中增加HttpServletRequest");
            throw new ATDException("request参数缺失", ErrorCode.INTERNAL_ERROR);
        }

        getJsonString(request, paramMap);
        if(paramMap.get("message") == null || paramMap.get("vendorId") == null || paramMap.get("sign") == null){
            LOGGER.warn("[AuthInterceptor], 未获取到参数,data:{}, vendorId:{}, sign:{}", paramMap.get("message"),
                    paramMap.get("vendorId"), paramMap.get("sign"));
            throw new ATDException("请检查data报文和sign签名和采购商id", ErrorCode.MESSAGE_MISS);
        }
        return paramMap;
    }

    /**
     * 获取 HttpServletRequest
     * @param args params
     * @return HttpServletRequest
     */
    private HttpServletRequest getRequest(Object[] args){
        for(Object obj : args){
            if(obj instanceof HttpServletRequest){
                return (HttpServletRequest)obj;
            }
        }
        return null;
    }

    /**
     * 将对象转换为json报文
     * @param request object to converted
     * @param paramMap vendorId 采购商id; message 报文; sign 签名
     */
    private void getJsonString(HttpServletRequest request, Map<String, String> paramMap) throws ATDException {
        try {
            String jsonStr = request.getParameter("json");
            JSONObject json = JSON.parseObject(jsonStr);
            paramMap.put("sign", json.getString("sign").replaceAll(" ", "+"));
            paramMap.put("vendorId", json.getString("purchaseId"));

            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(jsonStr);
            String param = m.replaceAll("");
            String message = param.substring(param.indexOf("data") - 1, param.length() -1);
            paramMap.put("message", message);
        } catch (Exception e) {
            LOGGER.error("[AuthInterceptor] [getJsonString]拼接参数时出错:{}", e.getMessage());
        }
    }

    /**
     * 鉴权计数器
     * @param key key
     */
    private void countAuth(final String key){

        aspectExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
                    final String hhMm = simpleDateFormat.format(new Date());
                    if(redisManager.ttl(key) < 0){
                        //过期 重置
                        redisManager.delKey(key);
                        redisManager.hIncr(key, hhMm, 1);
                        redisManager.expire(key, SECONDS);
                    } else {
                        redisManager.hIncr(key, hhMm, 1);
                    }
                } catch (Exception e) {
                    LOGGER.error("[AuthInterceptor] [countAuth]error:{}", e.getMessage());
                }
            }
        });
    }
}

3、threadPoolExecutor

<bean id = "aspectExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<!-- 线程池维护线程的最少数量 -->
		<property name ="corePoolSize" value ="5" />
		<!-- 线程池维护线程所允许的空闲时间 简单操作不允许超过200ms的处理时间-->
		<property name ="keepAliveSeconds" value ="200" />
		<!-- 线程池维护线程的最大数量 -->
		<property name ="maxPoolSize" value ="50" />
		<!-- 线程池所使用的缓冲队列 -->
		<property name ="queueCapacity" value ="200" />
	</bean>

4、apiAuth

/**
 * 需要进行鉴权的接口
 * Created by ysma on 2016/9/9.
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiAuth {

    /**加密方式*/
    String enCodeType() default "RSA";
}

5、RsaCrypt

package com.tuniu.air.ticket.channel.auth.crypt;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author ysma
 * Created on 2016/7/4.
 */
public class RsaCrypt {

    /**
     * 用私钥加密
     * @param data	加密数据
     * @param key	密钥
     * @return 密文
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data,String key) throws Exception {
        //解密密钥
        byte[] keyBytes = Coder.decryptBASE64(key);
        //取私钥
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RsaConstants.KEY_ALGORTHM);
        Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);


        return cipher.doFinal(data);
    }

    /**
     *	用私钥对信息生成数字签名
     * @param message	//报文
     * @param privateKey	//私钥
     * @return 签名
     * @throws Exception 异常
     */
    public static String sign(String message, String privateKey) throws Exception {
        String summary = Coder.encryptMD5(message.getBytes());

        byte[] bytes = RsaCrypt.encryptByPrivateKey(summary.getBytes(), privateKey);
        //解密私钥
        byte[] keyBytes = Coder.decryptBASE64(privateKey);
        //构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        //指定加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(RsaConstants.KEY_ALGORTHM);
        //取私钥匙对象
        PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        //用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(RsaConstants.SIGNATURE_ALGORITHM);
        signature.initSign(privateKey2);
        signature.update(bytes);

        return Coder.encryptBASE64(signature.sign());
    }

    /**
     * 校验数字签名
     * @param message	报文
     * @param publicKey	公钥
     * @param privateKey 私钥
     * @param sign	数字签名
     * @return 校验结果
     * @throws Exception
     */
    public static boolean verify(String publicKey, String privateKey, String message, String sign) throws Exception {
        String summary = Coder.encryptMD5(message.getBytes());
        byte[] bytes = RsaCrypt.encryptByPrivateKey(summary.getBytes(), privateKey);
        //解密公钥
        byte[] keyBytes = Coder.decryptBASE64(publicKey);
        //构造X509EncodedKeySpec对象
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        //指定加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(RsaConstants.KEY_ALGORTHM);
        //取公钥匙对象
        PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance(RsaConstants.SIGNATURE_ALGORITHM);
        signature.initVerify(publicKey2);
        signature.update(bytes);
        //验证签名是否正常
        return signature.verify(Coder.decryptBASE64(sign));
    }

}

6、RsaConstant

/**
 * Created by mayongsheng on 2016/7/4.
 */
public class RsaConstants {
    public static final String KEY_ALGORTHM="RSA";//
    public static final String SIGNATURE_ALGORITHM="MD5withRSA";

    public static final String PUBLIC_KEY = "publicKey";//公钥
    public static final String PRIVATE_KEY = "privateKey";//私钥

    /**1day unit:second */
    public static final long CACHE_TIME_DAY = 24*60*60;

    public static final String USER_KEY = "ASR:AUTH:USER:PURCHASE_ID:";
}

7、Coder

import org.apache.commons.codec.binary.Base64;

import java.security.MessageDigest;

public class Coder {
    
    public static final String KEY_SHA="SHA";
    public static final String KEY_MD5="MD5";
    public static final String KEY_BASE64="BASE64";
    
    /**
     * BASE64解密
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return Base64.decodeBase64(key);
    }
    
    /**
     * BASE64加密
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key)throws Exception {
        return Base64.encodeBase64String(key);
    }
    
    /**
     * MD5加密
     * @param data
     * @return
     * @throws Exception
     */
    public static String encryptMD5(byte[] data)throws Exception {
        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
        md5.update(data);
        byte[] mds = md5.digest();
        return toHex(mds);
    }

    /**
     * To hex
     *
     * @param bytes the bytes
     * @return the string
     */
    public static String toHex(byte bytes[]){
        StringBuilder hstr = new StringBuilder();
        String sTmp;
        for (int n = 0; n < bytes.length; n++) {
            sTmp = Integer.toHexString(bytes[n] & 0xff);
            if (sTmp.length() == 1){
                hstr.append("0").append(sTmp);
            } else {
                hstr.append(sTmp);
            }
        }
        return hstr.toString();
    }

}

8、AesCrypt

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * Created by ysma on 2016/9/9.
 */
public class AesCrypt {
	/**
	  * 加密
	  * @param content 需要加密的内容
	 * @param password  加密密码
	 * @return
	  */ 
	 public static byte[] encrypt(String content, String password) {
	         try {            
	                 KeyGenerator kgen = KeyGenerator.getInstance("AES");
	                 kgen.init(128, new SecureRandom(password.getBytes()));
	                 SecretKey secretKey = kgen.generateKey();
	                 byte[] enCodeFormat = secretKey.getEncoded(); 
	                 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
	                 Cipher cipher = Cipher.getInstance("AES");// 创建密码器
	                 byte[] byteContent = content.getBytes("utf-8"); 
	                 cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
	                 byte[] result = cipher.doFinal(byteContent); 
	                 return result; // 加密 
	         } catch (NoSuchAlgorithmException e) {
	                 e.printStackTrace(); 
	         } catch (NoSuchPaddingException e) {
	                 e.printStackTrace(); 
	         } catch (InvalidKeyException e) {
	                 e.printStackTrace(); 
	         } catch (UnsupportedEncodingException e) {
	                 e.printStackTrace(); 
	         } catch (IllegalBlockSizeException e) {
	                 e.printStackTrace(); 
	         } catch (BadPaddingException e) {
	                 e.printStackTrace(); 
	         } 
	         return null; 
	 } 
	 
	 /**解密
	  * @param content  待解密内容
	  * @param password 解密密钥
	  * @return
	   */ 
	  public static byte[] decrypt(byte[] content, String password) {
	          try { 
	                   KeyGenerator kgen = KeyGenerator.getInstance("AES");
	                   kgen.init(128, new SecureRandom(password.getBytes()));
	                   SecretKey secretKey = kgen.generateKey();
	                   byte[] enCodeFormat = secretKey.getEncoded(); 
	                   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
	                   Cipher cipher = Cipher.getInstance("AES");// 创建密码器
	                  cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
	                  byte[] result = cipher.doFinal(content); 
	                  return result; // 加密 
	          } catch (NoSuchAlgorithmException e) {
	                  e.printStackTrace(); 
	          } catch (NoSuchPaddingException e) {
	                  e.printStackTrace(); 
	          } catch (InvalidKeyException e) {
	                  e.printStackTrace(); 
	          } catch (IllegalBlockSizeException e) {
	                  e.printStackTrace(); 
	          } catch (BadPaddingException e) {
	                  e.printStackTrace(); 
	          } 
	          return null; 
	  }
	  
	  
	  /**将二进制转换成16进制
	   * @param buf
	    * @return
	    */ 
	   public static String parseByte2HexStr(byte buf[]) {
	           StringBuffer sb = new StringBuffer();
	           for (int i = 0; i < buf.length; i++) { 
	                   String hex = Integer.toHexString(buf[i] & 0xFF);
	                   if (hex.length() == 1) { 
	                           hex = '0' + hex; 
	                   } 
	                   sb.append(hex.toUpperCase()); 
	           } 
	           return sb.toString(); 
	   } 
	   
	   /**将16进制转换为二进制
	    * @param hexStr
	     * @return
	     */ 
	    public static byte[] parseHexStr2Byte(String hexStr) {
	            if (hexStr.length() < 1) 
	                    return null; 
	            byte[] result = new byte[hexStr.length()/2]; 
	            for (int i = 0;i< hexStr.length()/2; i++) { 
	                    int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
	                    int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
	                    result[i] = (byte) (high * 16 + low); 
	            } 
	            return result; 
	    } 
	    

	  public static void main(String[] args) {
		  String content = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
		  String password = "test";
		  //加密 
		 System.out.println("加密前:" + content);
		 byte[] encryptResult = encrypt(content, password);
		 String tt4 = Base64.encode(encryptResult);
		 System.out.println(new String(tt4));
		 
		  //解密 
		 byte[] decryptResult = decrypt(encryptResult,password); 
		 System.out.println("解密后:" + new String(decryptResult));
	}
}

 

转载于:https://my.oschina.net/ysma1987/blog/744663

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值