一、原理
JWT(Json Web Token)的获取和使用流程大致与OAuth2的授权码模式相同,
OAuth2的授权码模式在获取Token之后,第三方应用使用Token访问资源服务器,此时资源服务器会向授权服务器校验该Token是否正确。
而获取JWT之后,使用JWT去访问资源服务器获取资源,资源服务器会利用签名来校验该JWT是否正确(不必再去授权服务器校验),如果正确,则允许访问
二、使用
授权服务器搭建
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
2.授权服务器
另:用户登录认证和web安全配置请自行配置
@Configuration
@EnableAuthorizationServer //授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
//生成jwt
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("abc");//签名为"abc"
return jwtAccessTokenConverter;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("a")
.secret("$2a$10$QfvfRVwWr5twmp/DRYlOHOb7MSf9BXDkQa/MravLwJ8WmKo9D0aGm")
.authorizedGrantTypes("authorization_code")
.redirectUris("http://localhost:7070/login")
.scopes("userinfo");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)
.accessTokenConverter(jwtAccessTokenConverter());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();
}
}
资源服务器搭建
1.添加依赖
同授权服务器
2.资源服务器
资源服务器中设置的签名是用于校验,必须要与授权服务器中的签名相同
@Configuration
@EnableResourceServer
public class JwtResourceServer extends ResourceServerConfigurerAdapter {
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("abc");
return jwtAccessTokenConverter;
}
@Bean
public JwtTokenStore jwtTokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
//资源服务器要保存jwt信息,并且还要验证
resources.tokenStore(jwtTokenStore());
}
}
三、测试
获取授权码
- 访问授权服务器,地址为:
http://127.0.0.1:8080/oauth/authorize?client_id=a&response_type=code&redirect_uri=http://localhost:7070/login
2. 之后进入到一个登录页面,用户名密码填写在用户登录认证中的相应内容。
另:此处是自定义的登录页面,具体操作见:修改默认登录页面
3. 登录后出现询问是否授权页面
4. 点击授权,之后重定向到第1步中配置的地址并附带授权码
获取JWT
- 访问以下地址,获取JWT
http://127.0.0.1:8080/oauth/token?client_id=a&client_secret=1&grant_type=authorization_code&code=Ip65yU&redirect_uri=http://localhost:7070/login
重定向的uri必须带上"/login",否则会显示错误:“error_description”:“Redirect URI mismatch.”
- 访问后获取JWT
访问资源服务器
- 最后访问资源服务器时,带上access_token参数即可