small_925_ant
2020-05-04 21:13:12浏览 1472
上次简单学习了Spring Security,为了增强这方面的认识,今天继续来学习一下
Spring OAuth2。
OAuth2的角色和流程
角色:
1-客户端应用:用户直接访问,可以是web app或者手机app
2-认证服务器:分发令牌,客户端应用从认证服务器获取令牌,访问资源服务器
3-资源服务器:在微服务架构中就代表我们的微服务.
流程:
客户端应用从认证服务器获取令牌,客户端应用代表用户访问(资源服务)微服务,
微服务访问认证服务器来验证从客户端应用请求中获得的令牌是否有权限访问。
客户端应用和资源服务器都会和认证服务器进行交互。
更具体点就是说:
每个客户端应用都知道自己可以访问哪些资源。当客户端访问具体资源的时候,需要
根据客户端的名称密码等信息去认证服务器获取令牌,通过这个令牌就可以知道是否
可以访问某个资源。
代码开发
1-基础依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
2-认证服务器
(a)实现AuthorizationServerConfigurerAdapter授权服务器的配置类
@EnableAuthorizationServer 代表认证服务器
认证服务器需要知道有哪些合法用户和哪些合法的客户端应用
并且知道自己发出去的令牌可以用于访问哪些资源服务器。因此认证服务
器需要配置客户端应用的信息,可以存放在内存中获取持久化到数据库中。
这里以内存为案例:
配置客户端应用,让认证服务器知道有哪些客户端应用会来申请令牌:
clients.inMemory()
.withClient("orderApp")
.secret(passwordEncoder.encode("123456"))
.scopes("read","write")
.accessTokenValiditySeconds(3600)
.resourceIds("order-server")
.authorizedGrantTypes("password");
通过上面的配置可以知道客户端应用orderApp,可以访问的资源服务有
order-server。
(b)配置 WebSecurityConfigurerAdapter:配置合法的用户信息
UserDetailsService,如果不合法也不能申请令牌.
(c)AuthorizationServerSecurityConfigurer用来配置令牌端点的安全约
束.
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
完成以上配置就可以发送请求获取令牌,如:
http://localhost:9090/oauth/token
头部需要带有配置的客户端应用的信息如 orderApp,密码123456
并且需要传递用户信息和密码。
认证服务器接收到请求后会进行验证头部Authorization中客户端应用的
信息和用户信息。
3-配置资源服务器
实现ResourceServerConfigurerAdapter
@EnableResourceServer 说明服务是资源服务器,所有发往这个服务的请求都会被进行token校验:
ResourceServerConfigurerAdapter进行控制:
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
a-配置资源服务器,给资源服务器设置一个名称
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("order-server");
}
b-配置拦截哪些请求需要验证token,可以自己配置
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/haha").permitAll()
.anyRequest().authenticated();
}
c-资源服务器怎么验证令牌
资源服务器接收到请求后,需要验证令牌,才能决定是否可以被访问。所以
需要配置验证令牌的相关信息ResourceServerTokenServices:
@Bean
public ResourceServerTokenServices tokenServices(){
RemoteTokenServices tokenServices=new RemoteTokenServices();
tokenServices.setClientId("orderService");
tokenServices.setClientSecret("123456");
tokenServices.setCheckTokenEndpointUrl("http://localhost:9090/oauth/check_token");
//把令牌转为用户信息
tokenServices.setAccessTokenConverter(getAccessTokenConverte());
return tokenServices;
}
同样需要请求认证服务器,进行令牌的验证。
当被配置为一个资源服务器后,如果直接调用资源服务则会会返回401:
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
告诉我们需要先进行身份认证:
发请求获取token:
http://localhost:9090/oauth/token
获取到token后:
80c9ccc4-1f55-4d89-be01-00db32d506c3
然后在去请求。
持久化数据
到这里可以发现需要持久化的内容主要包含两个方面:
1-客户端应用的持久化
@Autowired
private DataSource dataSource;
配置:
clients.jdbc(dataSource);
这样我们就可以把客户端应用的名称密码以及可以访问哪些资源配置到
数据库中
2-令牌的信息
集群,不能单纯的放在内存
@Bean
public TokenStore tokenStore(){
return new JdbcTokenStore(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
未完待续