Spring Cloud Security OAuth2(一)—— 认证服务(上)
简介
介绍了Oauth2协议后,我们了解了资源服务器、认证服务器、第三方应用的概念。那我们马上动手简单体验一下Spring Cloud Security OAuth2吧。Spring Cloud Security OAuth2是基于Spring Security的,希望大家回顾一下之前的Spring Security文章,这也在之前Spring Security的项目上搭建认证服务器。
1.maven依赖
依赖同样是之前的依赖,这里我贴一下吧。
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<!--Spring Security Oauth2 Begin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!--Spring Security Oauth2 End-->
</dependencies>
2.认证服务器配置@EnableAuthorizationServer
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
/**
* @ClassName: CloudAuthorizationServerConfig
* @Description:
* @Author Marvin
* @Date 2019-06-04 15:52
*/
@Configuration
@EnableAuthorizationServer
public class CloudAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
// 支持password模式
@Autowired
private AuthenticationManager authenticationManager;
/**
* 密码加密
**/
@Autowired
private PasswordEncoder passwordEncoder;
/**
* @Author Marvin
* @Description 配置client信息
* @Date 16:07 2019-06-04
* @Param [clients]
* @return void
**/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("marvin") //clientId
.secret(passwordEncoder.encode("marvinSecret")) //clientSecret
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") //授权模式配置
.redirectUris("http://www.baidu.com") //授权码模式Callback的跳转url
.autoApprove(true) //是否自动确认授权,如果不是需要手动页面授权
.scopes("all"); //指定授权范围
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// password模式需要配置
endpoints.authenticationManager(authenticationManager);
}
}
这里注意的地方有2点:
- 1、需要把AuthenticationManager注入,然后配置到endpoints中。这样才能使用密码模式因为Spring Cloud Security OAuth2是这样规定的,可以看一下源码在AuthorizationServerEndpointsConfigurer中566行只有当authenticationManager不为空时,才会初始化密码模式的Granter。
- 2、需要配置客户端(即第三方应用)的信息,因为授权服务是为客户端服务的,需要明确给哪个客户端授权。
3.效果
经过上面简单的配置,可以初步实现认证服务器的四种授权模式了。这里使用postman来验证授权码模式和密码模式。
选择认证协议
授权码模式
到“自定义登陆页面”
输入账号密码后能获取到access_token
密码模式
然后直接能获取到access_token
总结
到这里,我们已经可以简单的实现认证服务器的功能了。旦有很多不足的地方,比如:
- 生成的access_token是随机的uuid,认证的时候资源服务器每次都需要调用认证接口来认证服务,对于微服务高并发的情况,大大增加了服务间调用的次数,从而增加了服务器压力。是否能有更好的方式(如jwt)生成access_token呢?
- client信息现在使用inMemory的配置,就是基于内存的,当服务器重启后就失效,我们需要配置基于jdbc的。