关于登陆授权拦截器 基于springboot

596 阅读2分钟

1.Application.class


import com.bochtec.clms.web.filter.JwtFilter;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;

/**
* @description:
* @author: tianjin
* @email: eternity_bliss@sina.cn
* @create: 2019-12-02 下午2:49
*/
@MapperScan(basePackages = {"com.bochtec.clms.dao"})
@SpringBootApplication
public class HandleApplication extends SpringBootServletInitializer {
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
      return builder.sources(HandleApplication.class);
  }
  /**
   * 过滤器
   */
  @Bean
  public FilterRegistrationBean jwtFilter() {
      final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
      //JwtFilter --token过滤自定义
      registrationBean.setFilter(new JwtFilter());
      registrationBean.addUrlPatterns("/clms/web/generalLoan/*", "/clms/web/specialLoan/*");
      return registrationBean;
  }
  public static void main(String[] args) {
      SpringApplication.run(HandleApplication.class, args);
  }
}

2.JwtFilter.class

import com.bochtec.clms.constant.JwtConstant;
import com.bochtec.clms.domain.CheckResult;
import com.bochtec.clms.util.TokenMgr;
import org.apache.catalina.servlet4preview.GenericFilter;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;

public class JwtFilter extends GenericFilter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        // jwt验证
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        System.out.println("自定义过滤器JwtFilter触发,拦截url:"+request.getRequestURI());
        //兼容多种token传输方式
        // 1.从Cookie获取jwt
        String token = getTokenFromCookie(request);
        if (StringUtils.isEmpty(token)) {
            // 2.从headers中获取
            token = request.getHeader("token");
        }
        if (StringUtils.isEmpty(token)) {
            // 3.从请求参数获取
            token = request.getParameter("token");
        }
        if (StringUtils.isEmpty(token)) {
            throw new ServletException("Missing or invalid token.");
        }
        
        CheckResult checkResult = TokenMgr.validateJWT(token);
        if (checkResult.isSuccess()) {
            request.setAttribute("claims",checkResult.getClaims());
            filterChain.doFilter(servletRequest,servletResponse);
        }
        else {
            if (checkResult.getErrCode().equals(JwtConstant.JWT_ERRCODE_EXPIRE)) {
                servletResponse.setCharacterEncoding("utf-8");
                PrintWriter printWriter = servletResponse.getWriter();
                printWriter.write("token过期,请重新登录");
                printWriter.flush();
                printWriter.close();
            }
            else if (checkResult.getErrCode().equals(JwtConstant.JWT_ERRCODE_FAIL)) {
                PrintWriter printWriter = servletResponse.getWriter();
                servletResponse.setCharacterEncoding("utf-8");
                printWriter.write("token验证失败!");
                printWriter.flush();
                printWriter.close();
            }
        }
    }

    private String getTokenFromCookie(HttpServletRequest request) {
        String token = null;
        Cookie[] cookies = request.getCookies();
        int len = null == cookies ? 0:cookies.length;
        if (len > 0) {
            for (int i=0;i<cookies.length;i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("token")) {
                    token = cookie.getValue();
                    break;
                }
            }
        }
        return token;
    }
    @Override
    public void destroy() {
    }
}

3.TokenMgr token工具类

import com.bochtec.clms.constant.JwtConstant;
import com.bochtec.clms.domain.CheckResult;
import io.jsonwebtoken.*;
import org.bouncycastle.util.encoders.Base64;

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

public class TokenMgr {
    public static SecretKey generalKey()  {
        byte[] encodedKey = Base64.decode(JwtConstant.JWT_SECURT);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 签发JWT
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     * @throws Exception
     */
    public static String createJWT(String id, String subject, long ttlMillis)  {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)
                .setIssuedAt(now)
                .signWith(signatureAlgorithm, secretKey);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate);
        }
        return builder.compact();
    }

    /**
     * 验证JWT
     * @param jwtStr
     * @return
     */
    public static CheckResult validateJWT(String jwtStr) {
        CheckResult checkResult = new CheckResult();
        Claims claims;
        try {
            claims = parseJWT(jwtStr);
            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(JwtConstant.JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }

    /**
     *
     * 解析JWT字符串
     * @param jwt
     * @return
     */
    public static Claims parseJWT(String jwt){
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
}

4.Loginservice.class

import com.bochtec.clms.common.response.Result;
import com.bochtec.clms.dao.UserMapper;
import com.bochtec.clms.domain.User;
import com.bochtec.clms.util.TokenMgr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;

import static com.bochtec.clms.constant.MagicConstant.NOT_ACCEPTABLE;
import static com.bochtec.clms.constant.MagicConstant.SUCCESS;
import static com.bochtec.clms.constant.MagicConstant.UNAUTHORIZED;

/**
 * @author: zhangyuhang
 * @modified By:
 * @date :Created in 2019/12/14 15:20
 **/
@Service
public class UserWebService {

    @Autowired
    UserMapper userMapper;
    
    public Result<String> login(String userName, String password)  {
        List<String> userNames = userMapper.selectByUserName(userName);
        if (userNames.size() <= 0) {
            return Result.error(NOT_ACCEPTABLE, "此用户不存在");
        }
        List<User> users = userMapper.selectByUserPass(userName, password);

        if (users.size() > 0) {
            String id= UUID.randomUUID().toString();
            String subject = "{role:1,permission:[1,2,3]}";
            /**
             * token id,权限和过期时间设置 缺省30分钟
             */
            String token = TokenMgr.createJWT(id,subject,30*60*1000L);
            System.out.println("TOKEN---------"+token);
            return Result.error(SUCCESS,token);
        } else {
            return Result.error(UNAUTHORIZED, "用户名密码不匹配");
        }
    }
}

5.Controller.class

import com.bochtec.clms.common.response.Result;
import com.bochtec.clms.web.request.UserReq;
import com.bochtec.clms.web.service.UserWebService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author: zhangyuhang
 * @modified By:
 * @date :Created in 2019/12/14 15:10
 **/
@Api(tags ="后台登陆")
@RestController
@RequestMapping("/clms/web")
public class LoginWebController {

    @Autowired
    UserWebService userWebService;

    @PostMapping("/login")
    @ApiOperation("登录")
    public Result<String> login(UserReq req)  {
        String username = req.getUserName();
        String password = req.getPassword();
        if (StringUtils.isBlank(username)) {
            return Result.ok("用户名不能为空");
        }
        if (StringUtils.isBlank(password)) {
            return Result.ok("密码不能为空");
        }
        return userWebService.login(username, password);
    }
}