SpringSecurtiy OAuth2 (5) Client Credentials Grant - 客户端模式

关于 SpringSecurity OAuth2 的 4 种模式的简要介绍性文章:
SpringSecurtiy OAuth2 (2) Authorization Code Grant - 授权码模式
SpringSecurtiy OAuth2 (3) Implicit Grant - 隐式授权模式
SpringSecurtiy OAuth2 (4) Resource Owner Password Grant - 密码模式
SpringSecurtiy OAuth2 (5) Client Credentials Grant - 客户端模式


更多细节和底层原理, 稍后会有专门的文章介绍.

关于

适用场景

适用于应用没有前端, 只有后端. 整个授权过程没有用户介入 (注意, 虽然密码模式也不需要前端, 但是是有用户信息介入的, 客户端授权模式是 4 种模式中唯一一种完全不需要用户介入的模式). 是第三方应用和授权服务器之间, “应用级别” 的行为.
直接与授权服务器交互, 用授权服务器颁发的客户端 ID 和客户端密钥直接去申请访问令牌.
请求 URL 形如:

http://localhost:18709/client-credentials-authorization-server/oauth/token?grant_type=client_credentials&client_id=client-a&client_secret=client-a-p

主要用于第一方应用.
譬如之前在公司中台做了一个对应全公司与外部多方财务系统的财务中间服务, 对内, 就是采取的客户端模式, 将公司内部产品视作客户端, 均要去中间服务申请客户端 ID 和客户端密钥, 然后在用这个凭证信息换取访问令牌以访问中间服务的资源.

整体流程

在这里插入图片描述

实现

代码结构

├─client-credentials-authorization-server
│  │  pom.xml
│  │  README.md
│  │  
│  └─src
│     └─main
│         ├─java
│         │  └─c
│         │      └─c
│         │          └─d
│         │              └─s
│         │                  └─s
│         │                      └─o
│         │                          └─c
│         │                              └─c
│         │                                  └─authorization
│         │                                      └─server
│         │                                          │  ClientCredentialsAuthorizationServer.java
│         │                                          │  
│         │                                          └─configuration
│         │                                                  AuthorizationServerConfiguration.java
│         │                                                  SecurityConfiguration.java
│         │                                                  
│         └─resources
│                 application.yml
│                 
└─client-credentials-resource-server
   │  pom.xml
   │  
   └─src
      └─main
          ├─java
          │  └─c
          │      └─c
          │          └─d
          │              └─s
          │                  └─s
          │                      └─o
          │                          └─c
          │                              └─c
          │                                  └─resource
          │                                      └─server
          │                                          │  ClientCredentialsResourceServer.java
          │                                          │  
          │                                          ├─configuration
          │                                          │      ResourceServerConfiguration.java
          │                                          │      
          │                                          └─controller
          │                                                  ResourceController.java
          │                                                  
          └─resources
                  application.yml

授权服务器 (Authorization Server)

AuthorizationServerConfiguration

由于客户端模式本身就是描述客户端和授权服务器之间的行为的, 所以在客户端模式的授权服务器代码中, 不需要额外指定其他的

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.allowFormAuthenticationForClients().checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // @formatter:off
        clients.inMemory()
                .withClient("client-a")
                .secret(passwordEncoder.encode("client-a-p")).resourceIds("resource-server")
                .authorizedGrantTypes("client_credentials")
                .scopes("access-resource")

                .and()
                .withClient("resource-server").secret(passwordEncoder.encode("resource-server-p"))
        ;
        // @formatter:on
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        super.configure(endpoints);
    }

    // ~ autowired
    // -----------------------------------------------------------------------------------------------------------------

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    // ~ bean
    // -----------------------------------------------------------------------------------------------------------------

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

SecurityConfiguration

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.formLogin().disable();
        http.httpBasic().disable();
        http.authorizeRequests().anyRequest().authenticated();
        // @formatter:on
    }
}

资源服务器 (Resource Server)

ResourceServerConfiguration

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("resource-server").tokenServices(remoteTokenServices()).stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
    }

    private RemoteTokenServices remoteTokenServices() {
        final RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:18709/client-credentials-authorization-server/oauth/check_token");

        // 客户端授权模式没有用户介入, 是应用程序和应用程序间的交互
        remoteTokenServices.setClientId("resource-server");
        remoteTokenServices.setClientSecret("resource-server-p");
        return remoteTokenServices;
    }
}

测试

在这里插入图片描述

总结

简单过了一遍最后一种授权模式: 客户端授权.
总的来说授权码模式隐式模式都需要前端和用户介入, 其中隐式模式甚至可以不需要后端; 密码模式虽然不需要前端支持, 但是仍然需要用户凭证; 而这最后一种客户端模式, 完全不需要用户介入, 是纯粹的客户端与授权服务器之间的行为. 非常适用于内部系统间的认证鉴权.


- To Be Continued -
- 接下来, 我们会详细探讨 Spring Security OAuth2 的更多自定义特性. 包含 ClientDetailsService, TokenGranter etc.

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值