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来验证授权码模式和密码模式。

选择认证协议

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_OAuth

授权码模式

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_Security_02


到“自定义登陆页面”

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_OAuth_03


输入账号密码后能获取到access_token

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_OAuth2_04

密码模式

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_OAuth2_05


然后直接能获取到access_token

springcloudgateway 实现oauth2登录验证 springcloud security oauth2_OAuth2_06

总结

到这里,我们已经可以简单的实现认证服务器的功能了。旦有很多不足的地方,比如:

  1. 生成的access_token是随机的uuid,认证的时候资源服务器每次都需要调用认证接口来认证服务,对于微服务高并发的情况,大大增加了服务间调用的次数,从而增加了服务器压力。是否能有更好的方式(如jwt)生成access_token呢?
  2. client信息现在使用inMemory的配置,就是基于内存的,当服务器重启后就失效,我们需要配置基于jdbc的。