SpringBoot 基于jjwt快速实现token授权

1、添加maven依赖注解

       <!--JJWT库-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.6.0</version> </dependency>

2、添加登录获取token时,所需要的认证信息类LoginPara.Java

/**
 * 添加登录获取token时,所需要的认证信息类LoginPara.Java
 * Created by CatalpaFlat on 2017/8/29.
 */
public class LoginPara { private String clientId; private String userName; private String password; public String getClientId() { return clientId; } public void setClientId(String clientId) { this.clientId = clientId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

3、添加token返回结果类AccessToken.java

/**
 * 添加token返回结果类AccessToken.java
 * Created by CatalpaFlat on 2017/8/29.
 */
public class AccessToken { private String access_token; private String token_type; private long expires_in; public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public String getToken_type() { return token_type; } public void setToken_type(String token_type) { this.token_type = token_type; } public long getExpires_in() { return expires_in; } public void setExpires_in(long expires_in) { this.expires_in = expires_in; } }

4、添加用于拼装token认证TokenObject类


/**
 * Created by CatalpaFlat on 2017/8/31.
 */
@Component
public class TokenObject { /**客户端id*/ private String clientId; /**base64加密*/ private String base64Secret; /**用户名*/ private String name; /**到期时间*/ private long expiresSecond; /**管理员名称*/ private String userName; /**管理员id*/ private Integer aId; /**职能*/ private String role; /**项目名称*/ private String project; public String getProject() { return project; } public void setProject(String project) { this.project = project; } public String getClientId() { return clientId; } public void setClientId(String clientId) { this.clientId = clientId; } public String getBase64Secret() { return base64Secret; } public void setBase64Secret(String base64Secret) { this.base64Secret = base64Secret; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getExpiresSecond() { return expiresSecond; } public void setExpiresSecond(long expiresSecond) { this.expiresSecond = expiresSecond; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Integer getaId() { return aId; } public void setaId(Integer aId) { this.aId = aId; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } }

5、添加构造jwt及解析jwt的帮助类JwtHelper.java

/**
 * 添加构造jwt及解析jwt的帮助类JwtHelper.java
 * Created by CatalpaFlat on 2017/8/29.
 */
public class JwtHelper { private static Logger logger = LoggerFactory.getLogger(JwtHelper.class); /** * 校验Token * @param jwt * @param httpRequest * @return */ public static int checkToken(String jwt, HttpServletRequest httpRequest){ if (!StringUtils.isBlank(jwt)){ if (jwt.split("\\.").length==3) { logger.info("jwt:" + jwt); String[] split = jwt.split("\\."); String content = split[1]; String s = Base64Codec.BASE64URL.decodeToString(content); logger.info("s:" + s); String sign = split[2]; logger.info("sign:" + sign); JSONObject jsonObject1 = JSONObject.fromObject(s); long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); long expiresSecond = (long) jsonObject1.get("expiresSecond"); //判断是否过期 if(now.getTime()>expiresSecond) return 2; TokenObject o = (TokenObject) JSONObject.toBean(jsonObject1, TokenObject.class); if (o!=null){ String project = o.getProject(); if (!StaticInfo.PROJECT.equals(project)) return 0; } String jwtByStr = createJWTByObj(o); String s2 = jwtByStr.split("\\.")[2]; logger.info("s2:" + s2); if (sign.equals(s2)) { return 1; } else return 0; } } return 0; } /** * 获取用户id * @param jwt * @return */ public static int getIdByJWT(String jwt){ if (!StringUtils.isBlank(jwt)) { if (jwt.split("\\.").length == 3) { logger.info("jwt:" + jwt); String[] split = jwt.split("\\."); String content = split[1]; String s = Base64Codec.BASE64URL.decodeToString(content); JSONObject jsonObject1 = JSONObject.fromObject(s); TokenObject o = (TokenObject) JSONObject.toBean(jsonObject1, TokenObject.class); return o.getaId(); } } return 0; } /** * 获取客户信息 * @param request * @return * @throws CustomException */ public static int getIdByRequest(HttpServletRequest request) throws CustomException { int i = 0; String auth = request.getHeader("Authorization"); if ((auth != null) && (auth.length() > 6)) { String HeadStr = auth.substring(0, 5).toLowerCase(); if (HeadStr.compareTo("basic") == 0) { auth = auth.substring(6, auth.length()); i = JwtHelper.getIdByJWT(auth); } } if (i==0) throw new CustomException(ResultEnum.PERMISSION_DENIED); return i; } public static String createJWTByObj(TokenObject tokenObject) { JSONObject jsonObject = JSONObject.fromObject(tokenObject); SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); //生成签名密钥 byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(tokenObject.getBase64Secret()); Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); //添加构成JWT的参数 JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT") .setHeaderParam("alg", "HS256") .setPayload(jsonObject.toString()) .signWith(signatureAlgorithm, signingKey); //生成JWT return builder.compact(); } } 

6、添加token过滤器 
(如果请求的Header中存在Authorization: Basic 头信息,且用户名密码正确,则继续原来的请求,否则返回没有权限的错误信息)


/**
 * 如果请求的Header中存在Authorization: Basic 头信息,且用户名密码正确,则继续原来的请求,否则返回没有权限的错误信息
 */
@WebFilter(filterName = "colationFilter", urlPatterns= "/colation/*")
public class HTTPBasicAuthorizeAttribute implements Filter{ private Logger logger = LoggerFactory.getLogger(HTTPBasicAuthorizeAttribute.class); @Autowired private Audience audience; @Override public void destroy() { logger.info("后台token过滤器,溜了溜了溜了溜了"); //可以日志管理添加 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("后台token过滤器检测"); //1.检测当前是否需要重新登录 if(audience!=null){ if (audience.getClientId().equals(StaticInfo.SIGNOUT)){ toResponse((HttpServletResponse) response,1,(HttpServletRequest) request); return; } } //2.检测请求同token信息 ResultEnum resultStatusCode = checkHTTPBasicAuthorize(request); if (resultStatusCode.equals(ResultEnum.SINGTIMEOUT)){//超时 toResponse((HttpServletResponse) response, 2,(HttpServletRequest) request); return; }else if (resultStatusCode.equals(ResultEnum.PERMISSION_DENIED)){//权限不够 toResponse((HttpServletResponse) response, 0,(HttpServletRequest) request); return; } logger.info("后台token过滤器检测通过"); chain.doFilter(request, response); } /** * 响应 * @param response * @param i 类型 * @throws IOException */ private void toResponse(HttpServletResponse response, int i,HttpServletRequest request) throws IOException { HttpServletResponse httpResponse = response; httpResponse.setCharacterEncoding("UTF-8"); httpResponse.setContentType("application/json; charset=utf-8"); httpResponse.setHeader("Access-Control-Allow-Origin","*"); httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); httpResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PATCH,PUT"); httpResponse.setHeader("Access-Control-Max-Age", "3600"); httpResponse.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,x-requested-with,X-Custom-Header," + "Content-Type,Accept,Authorization"); String method = request.getMethod(); if ("OPTIONS".equalsIgnoreCase(method)){ logger.info("OPTIONS请求"); httpResponse.setStatus(HttpServletResponse.SC_ACCEPTED); } ObjectMapper mapper = new ObjectMapper(); PrintWriter writer = httpResponse.getWriter(); if (i==1) writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.RESTARTLOGIN))); else if (i==2) writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.SINGTIMEOUT))); else writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.PERMISSION_DENIED))); writer.close(); if (writer!=null) writer = null; } @Override public void init(FilterConfig arg0) throws ServletException { logger.info("后台token过滤器启动"); } /** * 检测请求同token信息 * @param request * @return */ private ResultEnum checkHTTPBasicAuthorize(ServletRequest request) { try { HttpServletRequest httpRequest = (HttpServletRequest)request; String auth = httpRequest.getHeader("Authorization"); if ((auth != null) && (auth.length() > 6)) { String HeadStr = auth.substring(0, 5).toLowerCase(); if (HeadStr.compareTo("basic") == 0) { auth = auth.substring(6, auth.length()); int i = JwtHelper.checkToken(auth, httpRequest); if (i==1) { return ResultEnum.OK; }else if (i==2){ return ResultEnum.SINGTIMEOUT; } } } return ResultEnum.PERMISSION_DENIED; } catch(Exception ex) { return ResultEnum.PERMISSION_DENIED; } } }

7、测试token

/**
 * 登录退出-Controller
 * Created by CatalpaFlat on 2017/8/31.
 */
@RestController
@RequestMapping
public class AccoutController { @Autowired private AccountService accountService; /** * 登录 * @param loginPara * @param request * @return * @throws CustomException */ @PostMapping(value = "oauth/token") public Result getToken(LoginPara loginPara, HttpServletRequest request) throws CustomException { return accountService.getToken(loginPara,request); } /** * 退出 * @param request * @return */ @PostMapping(value = "singOut") public Result singOut(HttpServletRequest request){ return accountService.singOut(request); } }
/**
 * 登录-ServiceImpl
 * Created by CatalpaFlat on 2017/8/29.
 */
@Service
public class AccountServiceImpl implements AccountService { private Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class); @Autowired private AccountMapper accountMapper; @Autowired private Audience audience; @Autowired private TokenObject tokenObject; @Override public MangerInfo queryAccountByName(String userName) { return accountMapper.queryAccountByName(userName); } /** * 获取token * @param loginPara * @param request * @return */ @Override public Result getToken(LoginPara loginPara, HttpServletRequest request) throws CustomException { //获取登录ip String remoteHost = request.getRemoteHost(); String md5 = MD5Utils.getMD5(remoteHost); logger.info("md5:"+md5); loginPara.setClientId(md5); //第一个登录者 if (StaticInfo.SIGNOUT.equals(audience.getClientId())){ //修改配置文件 BeanWrapper bean = new BeanWrapperImpl(audience); bean.setPropertyValue("clientId", md5); audience.setClientId(md5); } audience.setClientId(md5); //校验是否已经登录着 // if(audience.getClientId()!=null&&(loginPara.getClientId().compareTo(audience.getClientId()) != 0)) // throw new CustomException(ResultEnum.ISSINGIMG); MangerInfo user = queryAccountByName(loginPara.getUserName()); if (user == null) throw new CustomException(ResultEnum.INVALID_PASSWORD); else { String md5Password = MD5Utils.getMD5(loginPara.getPassword()+user.getSalt()); if (md5Password.compareTo(user.getaPassword()) != 0) throw new CustomException(ResultEnum.INVALID_PASSWORD); } long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); //拼装accessToken tokenObject.setaId(user.getaId()); tokenObject.setBase64Secret(audience.getBase64Secret()); tokenObject.setClientId(audience.getClientId()); tokenObject.setExpiresSecond(audience.getExpiresSecond()+now.getTime()); tokenObject.setRole(user.getRole()); tokenObject.setUserName(loginPara.getUserName()); tokenObject.setName(audience.getName()); String token = JwtHelper.createJWTByObj(tokenObject); //返回accessToken AccessToken accessTokenEntity = new AccessToken(); accessTokenEntity.setAccess_token(token); accessTokenEntity.setExpires_in(audience.getExpiresSecond()); accessTokenEntity.setToken_type("basic"); return ResultUtils.success(accessTokenEntity); } @Override public Result singOut(HttpServletRequest request) { BeanWrapper bean = new BeanWrapperImpl(audience); bean.setPropertyValue("clientId", StaticInfo.SIGNOUT); return ResultUtils.success(); } }
测试结果
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DuShiWoDeCuo/article/details/78180701

猜你喜欢

转载自www.cnblogs.com/stupidMartian/p/9262980.html
今日推荐