OAuth2+JWT 实现权限验证( 三 )


然后再自定义有一个配置类,主要处理用户名和密码的校验等事宜 。
@Configurationpublic class SecurityConfiger extends WebSecurityConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;//@Autowired//private JdbcUserDetailsService jdbcUserDetailsService;/*** 注册一个认证管理器对象到容器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 密码编码对象(密码不进行加密处理)* @return*/@Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}/*** 处理用户名和密码验证事宜* 1)客户端传递username和password参数到认证服务器* 2)一般来说,username和password会存储在数据库中的用户表中* 3)根据用户表中数据,验证当前传递过来的用户信息的合法性*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 在这个方法中就可以去关联数据库了,当前我们先把用户信息配置在内存中// 实例化一个用户对象(相当于数据表中的一条用户记录)UserDetails user = new User("admin","123456",new ArrayList<>());auth.inMemoryAuthentication().withUser(user).passwordEncoder(passwordEncoder);//auth.userDetailsService(jdbcUserDetailsService).passwordEncoder(passwordEncoder);}}JWT 改造统?认证授权中?的令牌存储机制
JWT 令牌介绍
通过上边的测试我们发现,当资源服务和授权服务不在?起时资源服务使?RemoteTokenServices 远程请求授权 服务验证token,如果访问量较?将会影响系统的性能 。
解决上边问题: 令牌采?JWT格式即可解决上边的问题,?户认证通过会得到?个JWT令牌,JWT令牌中已经包括了?户相关的信 息,客户端只需要携带JWT访问资源服务,资源服务根据事先约定的算法??完成令牌校验,?需每次都请求认证 服务完成授权 。
什么是JWT?JSON Web Token(JWT)是?个开放的?业标准(RFC 7519),它定义了?种简介的、?包含的协议格式,?于 在通信双?传递json对象,传递的信息经过数字签名可以被验证和信任 。JWT可以使?Hmac算法或使?RSA的公 钥/私钥对来签名,防?被篡改 。
JWT令牌结构JWT 令牌由三部分组成,每部分中间使?点(.)分隔,?如:xxxxx.yyyyy.zzzzz
Header 。头部包括令牌的类型(即JWT)及使?的哈希算法(如HMAC SHA256或RSA),例如
{ "alg": "HS256", "typ": "JWT"}将上边的内容使?Base64Url编码,得到?个字符串就是JWT令牌的第?部分 。
Payload 。第?部分是负载,内容也是?个json对象,它是存放有效信息的地?,它可以存放jwt提供的现成字段,? 如:iss(签发者),exp(过期时间戳), sub(?向的?户)等,也可?定义字段 。此部分不建议存放敏感信息,因为此部分可以解码还原原始内容 。最后将第?部分负载使?Base64Url编码,得到?个字符串就是JWT令牌的第?部分 。?个例?:
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022}Signature 。第三部分是签名,此部分?于防?jwt内容被篡改 。这个部分使?base64url将前两部分进?编码,编码后使?点(.)连接组成字符串,最后使?header中声明 签名算法进?签名 。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

  1. base64UrlEncode(header):jwt令牌的第?部分 。
  2. base64UrlEncode(payload):jwt令牌的第?部分 。
secret:签名所使?的密钥 。
认证服务器端JWT改造(改造主配置类)
/*该方法用于创建tokenStore对象(令牌存储对象)token以什么形式存储*/public TokenStore tokenStore(){//return new InMemoryTokenStore();// 使用jwt令牌return new JwtTokenStore(jwtAccessTokenConverter());}/*** 返回jwt令牌转换器(帮助我们生成jwt令牌的)* 在这里,我们可以把签名密钥传递进去给转换器对象* @return*/public JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();jwtAccessTokenConverter.setSigningKey(sign_key);// 签名密钥jwtAccessTokenConverter.setVerifier(new MacSigner(sign_key));// 验证时使用的密钥,和签名密钥保持一致jwtAccessTokenConverter.setAccessTokenConverter(lagouAccessTokenConvertor);return jwtAccessTokenConverter;}修改 JWT 令牌服务?法
/** * 该方法用户获取一个token服务对象(该对象描述了token有效期等信息) */public AuthorizationServerTokenServices authorizationServerTokenServices() {// 使用默认实现DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setSupportRefreshToken(true); // 是否开启令牌刷新defaultTokenServices.setTokenStore(tokenStore());// 针对jwt令牌的添加defaultTokenServices.setTokenEnhancer(jwtAccessTokenConverter());// 设置令牌有效时间(一般设置为2个小时)defaultTokenServices.setAccessTokenValiditySeconds(20); // access_token就是我们请求资源需要携带的令牌// 设置刷新令牌的有效时间defaultTokenServices.setRefreshTokenValiditySeconds(259200); // 3天return defaultTokenServices;}


推荐阅读