java login jwt token filter

filter

package com.cwl.userdata.filter;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cwl.userdata.content.Constants;
import com.cwl.userdata.util.JwtTokenUtil;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.security.auth.Subject;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * @author LJQ E-mail:lijinquan@ishumei.com
 * @version 1.0
 * @date 创建时间:2018/11/12 16:36
 */
@Component
@Order(0)//指定过滤器的顺序 值越小越靠前
@WebFilter(urlPatterns = "/api/**", filterName = "tokenFilter")
public class TokenFilter extends OncePerRequestFilter {

    private final Logger logger = LoggerFactory.getLogger(TokenFilter.class);


    private final String[] noFilters = {"/api/excel", "/webdashboard/index", "doc", "/api/login","/csv/getToken",
            "/webjars/bycdao-ui/", "/swagger", "/json", ".js", ".css", ".ico", ".jpg", ".png",
            ".html", "/api/csv/download", "/api/csv/v2/download"};

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String uri = httpServletRequest.getRequestURI();
        System.out.println(uri);
        for (String s : noFilters) {
            if (uri.contains(s)) {
                //uri中包含不过滤uri,则不进行过滤
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>>放行url:" + uri);
                filterChain.doFilter(httpServletRequest, httpServletResponse);
                return;
            }
        }

        //获得头信息token
        String token = httpServletRequest.getHeader(Constants.JWT_HEADER);
        //如果token不为空且以特定的TOKEN_HEADER开头
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        if (token != null && (!"".equals(token)) && token.startsWith(Constants.JWT_TOKEN_HEADER)) {
            //对请求进行路由
            String jwt = "";
            try {
                jwt = token.substring(Constants.JWT_TOKEN_HEADER.length());
            } catch (Exception e) {
                //不对其进行路由
                httpServletResponse.setStatus(200);
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.getWriter().write("{\"code\":400,\"msg\":\"请重新登录!\",\"data\":null}");
                return;
            }

            if ("".equals(jwt)) {
                //不对其进行路由
                httpServletResponse.setStatus(200);
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.getWriter().write("{\"code\":400,\"msg\":\"请重新登录!\",\"data\":null}");
                return;
            }
            Claims claims = jwtTokenUtil.parseJWT(jwt);
            //验证token是否过期
            if (claims.getExpiration().before(new Date())) {
                this.logger.info("TokenFilter:token已过期");
                httpServletResponse.setStatus(200);
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.setContentType("{\"code\":300,\"msg\":\"请重新登录!\",\"data\":null}");
                return;
            }
            //验证token拥有者是否有效
            if (!claims.getIssuer().equals(Constants.JWT_ISSUSER)) {
                this.logger.info("TokenFilter:token发行者无效");
                httpServletResponse.setStatus(200);
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.getWriter().write("{\"code\":300,\"msg\":\"请重新登录!\",\"data\":null}");
                return;
            }
            String subject = claims.getSubject();
            Map maps = (Map) JSON.parse(subject);
            httpServletRequest.setAttribute("user", maps.get("user"));
            httpServletRequest.setAttribute("provinceCode", maps.get("provinceId"));
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            //不对其进行路由
            httpServletResponse.setStatus(200);
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            httpServletResponse.getWriter().write("{\"code\":400,\"msg\":\"请重新登录!\",\"data\":null}");
        }

    }
}

login

package com.cwl.userdata.controller;

import com.cwl.userdata.aspect.OperatorType;
import com.cwl.userdata.aspect.OperatorLog;
import com.cwl.userdata.aspect.TabType;
import com.cwl.userdata.content.Constants;
import com.cwl.userdata.entity.Account;
import com.cwl.userdata.service.AccountService;
import com.cwl.userdata.service.ProvinceService;
import com.cwl.userdata.util.JwtTokenUtil;
import com.cwl.userdata.vo.ResponseBean;
import com.cwl.userdata.vo.login.LoginVo;
import com.cwl.userdata.vo.login.UpdateUserVo;
import com.cwl.userdata.vo.login.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author ljq
 * @date 2020-01-11 11:50
 * @describe
 */
@RestController
@RequestMapping("/api")
@Api(tags = "登录接口")
public class LoginController {
    @Resource
    private AccountService accountService;
    @Resource
    private ProvinceService provinceService;

    @PostMapping("/login")
    @ApiOperation(value = "登录接口")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "success", response = UserVo.class),
            @ApiResponse(code = 501, message = "用户名或密码错误!"),
            @ApiResponse(code = 502, message = "验证码输入错误!"),
            @ApiResponse(code = 503, message = "未知错误!")
    })
    @OperatorLog(value = OperatorType.LOGIN, operatorModel = TabType.LOGIN)
    public ResponseBean login(@RequestBody LoginVo loginVo,
                              HttpServletRequest request) {
        String userAccount = loginVo.getUsername();
        String validCode = loginVo.getValidCode();
        try {
            HttpSession session = request.getSession(true);
            //检查验证码
            String sessionValidCode = (String) session.getAttribute(Constants.RAND_VALID_CODE);
            if (!StringUtils.isEmpty(validCode) && validCode.equalsIgnoreCase(sessionValidCode)) {
                Account a = new Account();
                a.setPassword(loginVo.getPassword());
                a.setUsername(loginVo.getUsername());
                Account account = accountService.login(a);
                if (null != account) {
                    //生成token
                    JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
                    String subject = JwtTokenUtil.generalSubject(account.getUsername(), account.getProvinceId());
                    String token = jwtTokenUtil.createJWT(userAccount, subject, Constants.JWT_TTL);
                    //将token返回
                    UserVo userVo = new UserVo();
                    userVo.setAccount(account);
                    userVo.setToken(token);
                    userVo.setProvinces(provinceService.getProvinces(account.getProvinceId()));
                    return ResponseBean.builder().code(200).data(userVo).msg("OK").build();
                }
                return ResponseBean.builder().code(501).data(false).msg("用户名或密码错误").build();
            } else {
                return ResponseBean.builder().code(502).msg("验证码输入错误!").data(false).build();
            }
        } catch (Exception e) {
            return ResponseBean.builder().code(503).msg("未知错误!").build();
        }
    }

    @PostMapping("/csv/getToken")
    @OperatorLog(value = OperatorType.LOGIN, operatorModel = TabType.LOGIN)
    public ResponseBean getToken(@RequestBody LoginVo loginVo,HttpServletRequest request) {
        String userAccount = loginVo.getUsername();
        try {
            Account a = new Account();
            a.setPassword(loginVo.getPassword());
            a.setUsername(loginVo.getUsername());
            Account account = accountService.login(a);
            if (null != account) {
                //生成token
                JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
                String subject = JwtTokenUtil.generalSubject(account.getUsername(), account.getProvinceId());
                String token = jwtTokenUtil.createJWT(userAccount, subject, Constants.JWT_TTL);
                //将token返回
                Map<String, String> map = new HashMap<>(1);
                map.put("token", token);
                return ResponseBean.builder().code(200).data(map).msg("OK").build();
            }
            return ResponseBean.builder().code(501).data(false).msg("用户名或密码错误").build();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseBean.builder().code(503).msg("未知错误!").build();
        }

    }


    @GetMapping("/login/validcode")
    @ApiOperation(value = "获取验证码")
    public ResponseBean validcode(HttpServletRequest request) {

        Random random = new Random();
        StringBuilder sRand = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand.append(rand);
        }
        // 将认证码存入SESSION
        request.getSession().setAttribute(Constants.RAND_VALID_CODE, sRand.toString());
        return ResponseBean.builder().code(200).msg("OK").data(sRand.toString()).build();
    }

    private Account getAccount(UpdateUserVo updateUserVo) {
        Account account = new Account();
        account.setUsername(updateUserVo.getUsername());
        account.setPassword(updateUserVo.getOldPassword());
        return account;
    }

    @ApiOperation(value = "验证旧密码正确")
    @PostMapping("/login/password")
    public ResponseBean getAccountByPassword(@RequestBody UpdateUserVo updateUserVo) {
        Account account = getAccount(updateUserVo);
        Account a = accountService.login(account);
        if (a == null) {
            return ResponseBean.builder().code(200).data(false).msg("旧密码错误").build();
        }
        return ResponseBean.builder().code(200).data(true).msg("旧密码正确").build();
    }

    @ApiOperation(value = "修改密码")
    @PostMapping("/login/password/update")
    @OperatorLog(value = OperatorType.UPDATE_PASSWORD, operatorModel = TabType.UPDATE_PASSWORD)
    public ResponseBean updatePassword(@RequestBody UpdateUserVo updateUserVo, HttpServletRequest request) {
        if (!updateUserVo.getNewPassword().equals(updateUserVo.getReNewPassword())) {
            return ResponseBean.builder().code(503).msg("重复输入密码不一致").build();
        }
        Account account = getAccount(updateUserVo);
        Account a = accountService.login(account);
        if (a == null) {
            return ResponseBean.builder().code(502).data(false).msg("旧密码错误").build();
        }
        a.setPassword(updateUserVo.getNewPassword());
        if (accountService.updatePassword(a)) {

            //修改操作录入数据库操作日志
            return ResponseBean.builder().code(200).msg("OK").build();
        }
        return ResponseBean.builder().code(501).msg("修改密码失败").build();
    }


    @PostMapping("/login/cz")
    @ApiOperation(value = "财政登录接口")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "success", response = UserVo.class),
            @ApiResponse(code = 501, message = "用户名或密码错误!"),
            @ApiResponse(code = 502, message = "验证码输入错误!"),
            @ApiResponse(code = 503, message = "未知错误!")
    })
    public ResponseBean czLogin(@RequestBody LoginVo loginVo,
                              HttpServletRequest request) {
        String userAccount = loginVo.getUsername();
        String validCode = loginVo.getValidCode();
        try {
            HttpSession session = request.getSession(true);
            //检查验证码
            String sessionValidCode = (String) session.getAttribute(Constants.RAND_VALID_CODE);
            if (!StringUtils.isEmpty(validCode) && validCode.equalsIgnoreCase(sessionValidCode)) {
                Account a = new Account();
                a.setPassword(loginVo.getPassword());
                a.setUsername(loginVo.getUsername());
                Account account = accountService.loginCz(a);
                if (null != account) {
                    //生成token
                    JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
                    String subject = JwtTokenUtil.generalSubject(account.getUsername(), account.getProvinceId());
                    String token = jwtTokenUtil.createJWT(userAccount, subject, Constants.JWT_TTL);
                    //将token返回
                    UserVo userVo = new UserVo();
                    userVo.setAccount(account);
                    userVo.setToken(token);
                    userVo.setProvinces(provinceService.getProvinces(account.getProvinceId()));
                    return ResponseBean.builder().code(200).data(userVo).msg("OK").build();
                }
                return ResponseBean.builder().code(501).data(false).msg("用户名或密码错误").build();
            } else {
                return ResponseBean.builder().code(502).msg("验证码输入错误!").data(false).build();
            }
        } catch (Exception e) {
            return ResponseBean.builder().code(503).msg("未知错误!").build();
        }
    }


}

token

package com.cwl.userdata.controller;

import com.cwl.userdata.content.Constants;
import com.cwl.userdata.util.JwtTokenUtil;
import com.cwl.userdata.vo.ResponseBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @author ljq
 * @date 2019-10-15 11:03
 * @describe
 */
@RestController
@RequestMapping("/api/token")
@Api(tags = "token验证")
public class TokenController {

    @ApiOperation(value = "token验证", notes = "大监控所有接口的有效性验证,通过登录时返回的'token'值进行权限验证")
    @GetMapping
    public ResponseBean testToken(HttpServletRequest httpServletRequest) {
        //获得头信息token
        String token = httpServletRequest.getHeader(Constants.JWT_HEADER);
        //如果token不为空且以特定的TOKEN_HEADER开头
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        if (token != null && (!"".equals(token)) && token.startsWith(Constants.JWT_TOKEN_HEADER)) {
            //对请求进行路由
            String jwt = token.substring(Constants.JWT_TOKEN_HEADER.length());
            System.out.println(jwt);
            return ResponseBean.builder().code(200).msg("OK").data(jwt).build();
        }
        return ResponseBean.builder().code(500).msg("token验证失败").build();
    }

}

util

package com.cwl.userdata.util;

import com.alibaba.fastjson.JSONObject;
import com.cwl.userdata.content.Constants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @author LJQ E-mail:lijinquan@ishumei.com
 * @version 1.0
 * @date 创建时间:2018/11/12 17:12
 * @parameter
 * @return
 * @since
 */
public class JwtTokenUtil {

    public SecretKey generalKey() {
        String stringKey = Constants.JWT_SECERT;
        byte[] encodedKey = Base64.decodeBase64(stringKey);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 创建jwt
     *
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public String createJWT(String id, String subject, long ttlMillis) {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey key = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                .signWith(signatureAlgorithm, key)
                .setIssuer(Constants.JWT_ISSUSER);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 解密jwt
     *
     * @param jwt
     * @return
     */
    public Claims parseJWT(String jwt) {
        SecretKey key = generalKey();
        Claims claims = Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(jwt).getBody();
        return claims;
    }

    /**
     * 生成subject信息
     *
     * @param
     * @return
     */
    public static String generalSubject(String user, String provinceCode) {
        JSONObject jo = new JSONObject();
        jo.put("user", user);
        jo.put("provinceId", provinceCode);
        return jo.toJSONString();
    }


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值