最近碰到APP开发权限验证的问题 用过滤器不能解决某些无需验证的方法 所以最终选择用AOP 解决
代码如下定义一个权限注解
- package com.thinkgem.jeesite.common.annotation;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- /**
- * 权限注解
- * Created by Hamming on 2016/12/26.
- */
- @Target(ElementType.METHOD)//这个注解是应用在方法上
- @Retention(RetentionPolicy.RUNTIME)
- public @interface AccessToken {
- /* String userId();
- String token();*/
- }
- package com.thinkgem.jeesite.common.aspect;
- import com.alibaba.fastjson.JSON;
- import com.thinkgem.jeesite.common.base.ResultApp;
- import com.thinkgem.jeesite.common.service.ApiService;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
- import org.springframework.web.context.request.ServletWebRequest;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * app身份验证
- * Created by Hamming on 2016/12/23.
- */
- @Aspect
- @Component
- public class AccessTokenAspect {
- @Autowired
- private ApiService apiService;
- @Before("@annotation(com.thinkgem.jeesite.common.annotation.AccessToken)")
- @ResponseBody
- public Object doAccessCheck()throws Throwable {
- HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
- String id = request.getParameter("id");
- String token = request.getParameter("token");
- boolean verify = apiService.verifyToken(id,token);
- if(verify){
- return true;
- }else {
- ServletRequestAttributes res = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- if (res == null) {
- throw new IllegalStateException("当前线程中不存在 Respnose上下文");
- }
- HttpServletResponse response = res.getResponse();
- response.reset();
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json; charset=utf-8");
- Map re = new HashMap<>();
- re.put("result",4);
- re.put("msg","token失效");
- String json = JSON.toJSONString(re);
- ServletOutputStream out = response.getOutputStream();
- OutputStreamWriter ow = new OutputStreamWriter(out,"UTF-8");
- try {
- ow.write(json);
- } finally {
- ow.flush();
- ow.close();
- }
- return false;
- }
- }
- }
- package com.thinkgem.jeesite.common.service;
- import com.thinkgem.jeesite.common.utils.JedisUtils;
- import io.jsonwebtoken.Jwts;
- import io.jsonwebtoken.SignatureAlgorithm;
- import io.jsonwebtoken.impl.crypto.MacProvider;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import redis.clients.jedis.Jedis;
- import java.io.*;
- import java.security.Key;
- import java.util.Date;
- /**
- *token登陆验证
- * Created by Hamming on 2016/12/23.
- */
- @Service
- public class ApiService {
- private static final String at="accessToken";
- public static Key key;
- // private Logger logger = LoggerFactory.getLogger(getClass());
- /**
- * 生成token
- * Key以字节流形式存入redis
- *
- * @param date 失效时间
- * @param appId AppId
- * @return
- */
- public String generateToken(Date date, String appId){
- Jedis jedis = null;
- try {
- jedis = JedisUtils.getResource();
- byte[] buf = jedis.get("api:key".getBytes());
- if (buf == null) { // 建新的key
- key = MacProvider.generateKey();
- ByteArrayOutputStream bao = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bao);
- oos.writeObject(key);
- buf = bao.toByteArray();
- jedis.set("api:key".getBytes(), buf);
- } else { // 重用老key
- key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf)).readObject();
- }
- }catch (IOException io){
- // System.out.println(io);
- }catch (ClassNotFoundException c){
- // System.out.println(c);
- }catch (Exception e) {
- // logger.error("ApiService", "generateToken", key, e);
- } finally {
- JedisUtils.returnResource(jedis);
- }
- String token = Jwts.builder()
- .setSubject(appId)
- .signWith(SignatureAlgorithm.HS512, key)
- .setExpiration(date)
- .compact();
- // 计算失效秒,7889400秒三个月
- Date temp = new Date();
- long interval = (date.getTime() - temp.getTime())/1000;
- JedisUtils.set(at+appId ,token,(int)interval);
- return token;
- }
- /**
- * 验证token
- * @param appId AppId
- * @param token token
- * @return
- */
- public boolean verifyToken(String appId, String token) {
- if( appId == null|| token == null){
- return false;
- }
- Jedis jedis = null;
- try {
- jedis = JedisUtils.getResource();
- if (key == null) {
- byte[] buf = jedis.get("api:key".getBytes());
- if(buf==null){
- return false;
- }
- key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf)).readObject();
- }
- Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody().getSubject().equals(appId);
- return true;
- } catch (Exception e) {
- // logger.error("ApiService", "verifyToken", key, e);
- return false;
- } finally {
- JedisUtils.returnResource(jedis);
- }
- }
- /**
- * 获取token
- * @param appId
- * @return
- */
- public String getToken(String appId) {
- Jedis jedis = null;
- try {
- jedis = JedisUtils.getResource();
- return jedis.get(at+appId);
- } catch (Exception e) {
- // logger.error("ApiService", "getToken", e);
- return "";
- } finally {
- JedisUtils.returnResource(jedis);
- }
- }
- }
spring aop配置
- <!--aop -->
- <!-- 扫描注解bean -->
- <context:component-scan base-package="com.thinkgem.jeesite.common.aspect"/>
- <aop:aspectj-autoproxy proxy-target-class="true"/>
验证权限方法使用 直接用注解就可以了AccessToken
例如
- package com.thinkgem.jeesite.modules.app.web.pay;
- import com.alibaba.fastjson.JSON;
- import com.thinkgem.jeesite.common.annotation.AccessToken;
- import com.thinkgem.jeesite.common.base.ResultApp;
- import com.thinkgem.jeesite.modules.app.service.pay.AppAlipayConfService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.ResponseBody;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * 支付接口
- * Created by Hamming on 2016/12/27.
- */
- @Controller
- @RequestMapping(value = "/app/pay")
- public class AppPayModule {
- @Autowired
- private AppAlipayConfService appAlipayConfService;
- @RequestMapping(value = "/alipay", method = RequestMethod.POST, produces="application/json")
- @AccessToken
- @ResponseBody
- public Object alipay(String orderId){
- if(orderId ==null){
- Map re = new HashMap<>();
- re.put("result",3);
- re.put("msg","参数错误");
- String json = JSON.toJSONString(re);
- return json;
- }else {
- return null;
- }
- }
- }