传说中的jwt,我们来征服一下( 二 )

可以看到 , 我们同样传入了一个secret , 如果这个secret被篡改了 , 那么这段代码将会抛出SignatureException异常 。
这就是jwt的全部 。 大家记住这两个方法 , 我们的集成验证 , 都是基于这两个方法进行的 。
将其集成在SpringBoot项目中
在SpringBoot体系中 , 使用最多的认证框架 , 就是亲生的Spring Security 。 其实jwt本身是没有什么难度的 , 难就难在和Spring Security的集成上 , 也就是Spring Security的知识更多一些 。
传说中的jwt,我们来征服一下文章插图
如上图 , 我们把对Jwt使用流程 , 拆封成两部分 。 第一部分是登录 , 使用普通的Controller即可完成 。 第二部分是jwt验证 , 我们使用拦截器的方式去解决 。
2.安全配置我们使用WebSecurityConfigurerAdapter来完成Spring Security的配置 。 主要代码分3部分 。
第一 , 用户数据来源@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}这段代码 , 配置了用户数据来源 , 以及对于密码的摘要算法 。 这里采用的是安全系数较高的BCrypt 。 也就是说 , 我们在MySQL里保存的是BCrypt摘要的密码 , SpringSecurity会根据这个算法算出我们输入密码的摘要 , 进行对比 。
@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(); }我们模拟了一个真实存在的用户数据源 , 下面是JwtUserDetailsServiceImpl的代码 。 意思是所有用户的密码 , 都是123456 。
JwtUserDetailsServiceImpl.java
@Servicepublic class JwtUserDetailsServiceImpl implements UserDetailsService {/*** 已经在 WebSecurityConfig 中生成*/@AutowiredPasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {return new User(username, mockPassword(), getAuthorities());}private String mockPassword() {return passwordEncoder.encode("123456");}private Collection getAuthorities() {List authList = new ArrayList();authList.add(new SimpleGrantedAuthority("ROLE_USER"));authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));return authList;}}第二 , 白名单配置我们希望有些链接 , 是不走SpringSecurity的拦截器的 , 比如swagger , 比如login方法 , 这就需要在全局配置中进行忽略配置 。
重写configure方法可以忽略某些链接 。
String[] SWAGGER_WHITELIST = {"/swagger-ui.html","/swagger-ui/**","/swagger-resources/**","/v2/api-docs","/v3/api-docs","/webjars/**"};@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers(SWAGGER_WHITELIST).antMatchers("/login**") ;}第三 , 配置过滤器当然 , 里面还有一个configure方法 , 这次的参数是HttpSecurity 。 我们在这里添加上自定义的JwtRequestFilter到UsernamePasswordAuthenticationFilter之前 。
filter一般都是责任链模式 , 所以会有顺序问题 。
@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.cors().and().csrf().disable().authorizeRequests().antMatchers(SWAGGER_WHITELIST).authenticated().anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().addFilterBefore(new JwtRequestFilter(), UsernamePasswordAuthenticationFilter.class);}


推荐阅读