首先需要创建2个过滤器. JwtLoginFilter 和 JwtAuthenticationFilter .

JwtLoginFilter 用来处理用户登录请求.

JwtAuthenticationFilter 用来处理JwtToken的验证解析.

/*** @author: 阮胜* @date: 2018/7/10 8:42*/
public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {private static final String POST = "POST";private AuthenticationSuccessHandler successHandler = new JwtLoginSucessHandler();private AuthenticationFailureHandler failureHandler = new JwtLoginFailureHandler();public JwtLoginFilter(AuthenticationManager authenticationManager) {super(new AntPathRequestMatcher("/user/login", "POST"));setAuthenticationManager(authenticationManager);}@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)throws AuthenticationException, IOException, ServletException {if (!request.getMethod().equals(POST)) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String username = request.getParameter("username");String password = request.getParameter("password");if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {PrintWriter writer = response.getWriter();writer.write("用户名或者密码为空");writer.close();return null;}username = username.trim();UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);authRequest.setDetails(authenticationDetailsSource.buildDetails(request));return this.getAuthenticationManager().authenticate(authRequest);}@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();JwtToken jwtToken = new JwtToken(authResult.getName(), authResult.getAuthorities().iterator().next().toString(), jwtTokenUtil.generateExpirationDate());String jwtTokenStr = jwtTokenUtil.generateToken(jwtToken);response.addHeader("Authorization", jwtTokenStr);successHandler.onAuthenticationSuccess(request, response, authResult);}@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {failureHandler.onAuthenticationFailure(request, response, failed);}public void setSuccessHandler(AuthenticationSuccessHandler successHandler) {this.successHandler = successHandler;}public void setFailureHandler(AuthenticationFailureHandler failureHandler) {this.failureHandler = failureHandler;}
}


/*** @author: 阮胜* @date: 2018/7/10 10:44*/
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {super(authenticationManager);}@Autowiredprivate JwtTokenUtil jwtTokenUtil;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {String jwtTokenStr = request.getHeader("Authorization");if (!StringUtils.isEmpty(jwtTokenStr)) {try {if (!jwtTokenUtil.validateToken(jwtTokenStr)) {throw new InvalidJwtTokenException();}JwtToken jwtToken = jwtTokenUtil.parseJwtToken(jwtTokenStr);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(jwtToken.getUsername(), null, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_".concat(jwtToken.getRole())));SecurityContextHolder.getContext().setAuthentication(authenticationToken);} catch (Exception e) {sendError(response, "无效的Token");return;}}chain.doFilter(request, response);}private void sendError(HttpServletResponse response, String msg) throws IOException {response.setStatus(HttpServletResponse.SC_BAD_REQUEST);response.setContentType("text/plain;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(msg);writer.close();}
}

配置类:

/*** @author: 阮胜* @date: 2018/7/10 8:33*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {private final AccessDeniedHandler accessDeniedHandler;private final AuthenticationEntryPoint authenticationEntryPoint;private final UserDetailServiceImpl userDetailsService;public SecurityConfig(AccessDeniedHandler accessDeniedHandler, AuthenticationEntryPoint authenticationEntryPoint, UserDetailServiceImpl userDetailsService) {this.accessDeniedHandler = accessDeniedHandler;this.authenticationEntryPoint = authenticationEntryPoint;this.userDetailsService = userDetailsService;}@Beanpublic PasswordEncoder passwordEncoder() {return new DefaultEncoder();}@Beanpublic JwtLoginFilter jwtLoginFilter() throws Exception {JwtLoginFilter jwtLoginFilter = new JwtLoginFilter(authenticationManager());jwtLoginFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {System.out.println("success");});jwtLoginFilter.setAuthenticationFailureHandler((request, response, exception) -> {System.out.println("false");});return jwtLoginFilter;}@Beanpublic JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {return new JwtAuthenticationFilter(authenticationManager());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin", "/admin/info").hasRole("ADMIN").anyRequest().permitAll().and().userDetailsService(userDetailsService)//如果已经登录,但没有访问资源的权限,则调用该Handler
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler)//如果未登录,没有权限则调用该EntryPoint
                .authenticationEntryPoint(authenticationEntryPoint)// 无状态的Session机制(即Spring不使用HTTPSession),对于所有的请求都做权限校验
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//关闭跨域保护
                .and().csrf().disable();//把自己写的2个filter加入到过滤器链中http.addFilterBefore(jwtLoginFilter(), UsernamePasswordAuthenticationFilter.class).addFilter(jwtAuthenticationFilter());}
}

工具类:

package com.example.springsecurityjwtdemo.util;import com.example.springsecurityjwtdemo.exception.InvalidJwtTokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** @author 阮胜* @date 2018/7/5 21:21*/
@Component
public class JwtTokenUtil implements Serializable {private static final long serialVersionUID = -3301605591108950415L;public static final String USERNAME = "username";public static final String ROLE = "role";public static final String CREATED_DATE = "createdDate";private static final String SECRET = "jwt_secret";private static final int EXPIRED_TIME_SECONDS = 60 * 60 * 24 * 7;public JwtToken parseJwtToken(String token) throws InvalidJwtTokenException {Claims claims = obtainClaims(token);if (claims == null) {throw new InvalidJwtTokenException();}return new JwtToken(claims.get(USERNAME).toString(), claims.get(ROLE).toString(), claims.get(CREATED_DATE, Date.class));}public String obtainUsername(String token) {String username;try {final Claims claims = obtainClaims(token);username = claims.getSubject();} catch (Exception e) {username = null;}return username;}public Date obtainExpiredDate(String token) {Date expiration;try {final Claims claims = obtainClaims(token);expiration = claims.getExpiration();} catch (Exception e) {expiration = null;}return expiration;}private Claims obtainClaims(String token) {Claims claims;try {claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();} catch (Exception e) {claims = null;}return claims;}public Date generateExpirationDate() {long expired = System.currentTimeMillis() + EXPIRED_TIME_SECONDS * 1000;return new Date(expired);}private boolean isTokenExpired(String token) {final Date expiration = obtainExpiredDate(token);return expiration.after(new Date());}public String generateToken(UserDetails userDetails) {return generateToken(new JwtToken(userDetails.getUsername(), userDetails.getAuthorities().iterator().next().toString(), new Date()));}private String generateToken(Map<String, Object> claims) {return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate()).signWith(SignatureAlgorithm.HS512, SECRET).compact();}public String generateToken(JwtToken jwtToken) {HashMap<String, Object> tokenMap = new HashMap<>(3);tokenMap.put(JwtTokenUtil.USERNAME, jwtToken.getUsername());tokenMap.put(JwtTokenUtil.CREATED_DATE, jwtToken.getExpiredDate());tokenMap.put(JwtTokenUtil.ROLE, jwtToken.getRole());return generateToken(tokenMap);}public boolean validateToken(String token) {Date expiredDate = obtainExpiredDate(token);return expiredDate != null && expiredDate.after(new Date());}
}

package com.example.springsecurityjwtdemo.util;import lombok.Data;import java.util.Date;/*** @author 阮胜* @date 2018/7/5 20:54*/
@Data
public class JwtToken {private String username;private String role;private Date expiredDate;public JwtToken() {}public JwtToken(String username, String role, Date expiredDate) {this.username = username;this.role = role;this.expiredDate = expiredDate;}
}

转载于:https://www.cnblogs.com/cearnach/p/9288971.html

Spring Security JWT相关推荐

  1. springboot jwt token前后端分离_基于Spring Boot+Spring Security+JWT+Vue前后端分离的开源项目...

    一.前言 最近整合Spring Boot+Spring Security+JWT+Vue 完成了一套前后端分离的基础项目,这里把它开源出来分享给有需要的小伙伴们 功能很简单,单点登录,前后端动态权限配 ...

  2. 超实用,Spring Security+JWT+Vue实现一个前后端分离无状态认证Demo

    作者: 陕西颜值扛把子 https://zhuanlan.zhihu.com/p/95560389 精彩推荐 一百期Java面试题汇总 SpringBoot内容聚合 IntelliJ IDEA内容聚合 ...

  3. spring boot +spring security + jwt 实现认证模块

    我在使用spring进行开发时,通常是使用 aop+jwt 模式来对调用者身份进行确认.前几天接触到一个开源商城源码(github地址)里面使用spring security +jwt 来进行权限的验 ...

  4. Spring boot 整合Spring Security Jwt

    记录学习Spring boot 整合Spring Security Jwt 学习参考 – 慢慢的干货 https://shimo.im/docs/OnZDwoxFFL8bnP1c/read 首先创建S ...

  5. Spring Boot + Spring Security + JWT + 微信小程序登录

    Spring Boot + Spring Security + JWT + 微信小程序登录整合教程 参考文章 文章目录 整合思想 整合步骤 1. AuthenticationToken 2. Auth ...

  6. Spring Security + JWT实现权限管理

    1 写在之前 本博客主要使用Spring Boot 整合Spring Security + JWT实现权限管理,利用JWT工具生成token,返回给登录接口.在访问其他接口时,采用Bearer Tok ...

  7. spring security+jwt 登录认证

    spring security+jwt 登录认证 1.综述 2.版本与环境 3.架构 4.数据库认证逻辑图 5.案例 security+jwt 5.1引入依赖 5.2新建工具类 5.2新建组件类 5. ...

  8. Springboot Spring Security +Jwt+redis+mybatisPlus 动态完成 前后端分离认证授权

    Springboot Spring Security +Jwt 动态完成 前后端分离认证授权 文章目录 Springboot Spring Security +Jwt 动态完成 前后端分离认证授权 前 ...

  9. Spring Boot+Spring Security+JWT 实现token验证

    Spring Boot+Spring Security+JWT 实现token验证 什么是JWT? JWT的工作流程 JWT的主要应用场景 JWT的结构 SpringBoot+Spring Secur ...

  10. Angular 6集成Spring Boot 2,Spring Security,JWT和CORS

    主要内容:Spring Boot 2的基础应用.CORS配置.Actuator监控:Spring Boot集成springfox-swagger,利用Swagger生成JSON API文档,利用Swa ...

最新文章

  1. Vivado IP核生成设置
  2. CentOS7开机启动图形界面的开启与关闭
  3. phpstorm-有关设置
  4. 配置 tsconfig.json
  5. HDU-1518 Square dfs+剪枝
  6. oracle事务提交前更新机制,Oracle 事务机制 批量添加,修改,更新
  7. 【转载】DRuid 大数据分析之查询
  8. git 命令详解和常见问题解决
  9. Mac osx 下配置ANT
  10. getAttribute和getParameter的区别
  11. php在线考试系统详细步骤
  12. 使用canvas把照片旋转任意角度
  13. Particleground 粒子特效插件
  14. On-Screen Keyboard(屏幕键盘) v7.0.2pro注册版
  15. 微软产品下载地址。MSDN 我告诉你。
  16. bouncing results问题
  17. 给所有的Control加两个属性,实现回车键自动跳转到下一个控件
  18. 香港HongKong之旅
  19. python scrapy爬虫视频_python爬虫scrapy框架的梨视频案例解析
  20. HDU 4507 吉哥系列故事——恨7不成妻(数位DP)

热门文章

  1. 圣诞好礼之Grid视频
  2. c语言考试常考大题,C语言题库经典题 考试常考题.doc
  3. mysql clomn_mysql 命令总结
  4. datatable更新到mysql_.NET_使用DataTable更新数据库(增,删,改),1、修改数据复制代码 代码如 - phpStudy...
  5. java中多态_java之多态
  6. php数据库框架 edusoho,CentOS 6.x + Apache+ PHP + MySQL + EduSoho[文档]
  7. 7z替换exe文件内容不能替换文件_windows/system32文件夹权限问题
  8. 心语收集14:人生没有如果,但是有很多但是;人生不能后悔,但是可以拐弯。...
  9. ARIS业务流程建模工具培训
  10. LaTeX的历史:图灵奖得主1977年开启的计划,引发学术圈重大变革