spring cloud oauth2 微服务 统一认证授权 框架搭建

2020-03-06 16:25:47 | 编辑

之前的一篇文章讲解了spring cloud搭建使用方法:SpringBoot + SpringCloud Feign 多模块 框架搭建案例 ,这一篇 记录 spring cloud oauth2微服务 统一认证授权 框架搭建。这里依然是最简单的方式实现统一认证,是纯client模式,如果要使用数据库,用户,权限等,可以在此基础上继续开发。

 

1.要实现的目标

spring cloud有很多服务组件,不同的组件提供不同的服务,有第三方应用,web,app,小程序等,需要调用这些服务,需要获取token 令牌,才能访问这些服务,而且一个token 令牌可以访问所有的服务。

就像微信公众平台,阿里平i台一样,调用接口需要先获取token,调用接口带着token令牌,然后平台再对token验证,有权限才可以调用。

这就是我要实现的统一验证授权框架。

 

2.搭建统一认证服务 service-auth

service-auth服务 用来获取token,验证token

2.1 pom 依赖

    <dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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>
	
	    <!-- 可以选择 注册到 eureka
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        -->

    </dependencies>

打开spring-cloud-starter-oauth2依赖可以看到,它已经整合了spring-cloud-starter-security、spring-security-oauth2 和 spring-security-jwt 这3个基本依赖。

2.2 继承 AuthorizationServerConfigurerAdapter 配置 权限服务

/**
 * 启用权限服务,作为统一鉴权服务器
 * @Author: houyong
 * @Date: 2019/11/14
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;


    /**
     * 指定client凭证,不需要考虑用户权限,只使用 client_credentials 模式鉴权
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //配置客户端凭证
        clients.inMemory()
                .withClient("cloudClientId")
                .secret("{noop}cloudClientSecret")
                .scopes("all");
    }


}

 

2.3 启用 ResourceServer 资源服务

这里就是为了启用注解@EnableResourceServer,也有可能有更深入的配置,如果没有,加载启动类上是一样的

@Configuration
@EnableResourceServer
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
}

 

2.4 配置 启用spring security

更深入的用户,权限 ,用户数据库配置 都可以配置在这里,我这里就用最简单的默认用户权限实现

/**
 * 使用Security来保护项目
 * @Author: houyong
 * @Date: 2019/11/13
 */

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

}

 

2.5 获取当前用户接口

用来获取验证token的当前用户

/**
 * @Author: houyong
 * @Date: 2019/11/15
 */
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
    @RequestMapping("current")
    public Principal user(Principal user) {
        log.warn("### getCurrent"+ JSON.toJSONString(user));
        return user;
    }
}

 

2.6 启动类

@SpringBootApplication
//@EnableEurekaClient 可以选择注册到eureka
public class ServiceAuthApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceAuthApplication.class, args);
    }

}

 

2.7 application.properties

spring.application.name=service-auth

server.port=8100

#eureka.client.service-url.defaultZone=http://127.0.0.1:8000/eureka/

 

2.8 测试启动认证服务 service-auth 获取token

直接访问http://localhost:8100/user/current 显示无权限

http://localhost:8100/oauth/token 获取token

选择Basic Auth 填写前面配置的客户端凭证,并且 传递body 参数 grant_type=client_credentials

使用获得的token再次访问 http://localhost:8100/user/current,返回用户信息

 

3.客户端服务搭建 product-server

搭建一个第三方要使用这个 service-auth 统一验证的服务,商品管理服务product-server

3.1 pom

    <dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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>
	
	    <!-- 可以选择 注册到 eureka
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        -->

    </dependencies>

 

3.2 OAuth2ClientConfig 类

下面配置是为了解决 spring cloud feign 内部服务间调用 没有token的问题,因为所有接口都被保护起来了,没有token就访问不了

@Configuration
@EnableOAuth2Client //作为 Oauth2 客户端
@EnableResourceServer //提供商品服务,所以也是资源服务器
public class OAuth2ClientConfig {

    /**
     * 下面两个bean配置 是为了解决 feign 模式下 统一验证凭证的问题
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "security.oauth2.client")
    public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
        return new ClientCredentialsResourceDetails();
    }
    @Bean
    public RequestInterceptor oauth2FeignRequestInterceptor(){
        return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());
    }

}

 

3.3 启动类



//@EnableEurekaClient //可以开启注册到eureka
//@EnableFeignClients(basePackages = "net.itxw.demo")
@SpringBootApplication
public class ProductServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductServerApplication.class, args);
    }

}

 

3.4.application.properties


spring.application.name=product-server
server.port=8001

#可以选择注册到eureka
#eureka.client.service-url.defaultZone=http://127.0.0.1:8000/eureka/
#spring.main.allow-bean-definition-overriding=true

#security 客户端凭证对应 service-auth 配置
security.oauth2.client.access-token-uri=http://localhost:8100/oauth/token
security.oauth2.resource.user-info-uri=http://localhost:8100/user/current
security.oauth2.client.grant-type=client_credentials
security.oauth2.client.client-id=cloudClientId
security.oauth2.client.client-secret=cloudClientSecret

 

3.5 编写测试controller

@RestController
public class TestController {
    
    @RequestMapping("/getProduct")
    public String getProduct(){
        return "您要获取的商品来了!";
    }
}

 

4.整体测试统一验证服务

4.1 调用product-server  http://localhost:8001/getProduct

显示无权限

使用上面service-auth 获取的token 再次访问

访问成功!

spring cloud oauth2 微服务 统一认证授权 框架搭建 就这么顺利的完成了!!!

登录后即可回复 登录 | 注册
    
关注编程学问公众号