加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 服务器 > 系统 > 正文

Spring OAuth2 授权服务器配置介绍

发布时间:2022-06-21 13:33:50 所属栏目:系统 来源:互联网
导读:前两篇文章分别体验了Spring Authorization Server的使用和讲解了其各个过滤器的作用。今天来讲讲Spring Authorization Server授权服务器的配置。强烈建议自己手动搭建一次试试,纸上得来终觉浅,深知此事要躬行。提升你的代码量才是提高编程技能的不二法门
  前两篇文章分别体验了Spring Authorization Server的使用和讲解了其各个过滤器的作用。今天来讲讲Spring Authorization Server授权服务器的配置。强烈建议自己手动搭建一次试试,纸上得来终觉浅,深知此事要躬行。提升你的代码量才是提高编程技能的不二法门,这也是本篇教程的意义所在。
 
  配置依赖
  首先要创建一个Spring Boot Servlet Web项目,这个不难就不赘述了。集成Spring Authorization Server需要引入:
 
  复制
  <!--  spring security starter 必须  -->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-oauth2-authorization-server</artifactId>
  <!--  截至现在版本  -->
      <version>0.2.0</version>
  </dependency>
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  OAuth2.0 Client客户端需要注册到授权服务器并持久化,Spring Authorization Server提供了JDBC实现,参见JdbcRegisteredClientRepository。为了演示方便这里我采用了H2数据库,需要以下依赖:
 
  复制
  <!--  jdbc 必须引入否则自行实现  -->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
  </dependency>
  <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
  </dependency>
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  生产你可以切换到其它关系型数据库,数据库脚本在Spring Authorization Server入门 一文的DEMO中。
 
  Spring Authorization Server配置
  接下来是Spring Authorization Server的配置。
 
  过滤器链配置
 
  根据上一文对过滤器链的拆解,我们需要在Spring Security的过滤器链中注入一些特定的过滤器。这些过滤器的配置由OAuth2AuthorizationServerConfigurer来完成。以下为默认的配置:
 
  复制
  void defaultOAuth2AuthorizationServerConfigurer(HttpSecurity http) throws Exception {
       OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
               new OAuth2AuthorizationServerConfigurer<>();
       // TODO 你可以根据需求对authorizationServerConfigurer进行一些个性化配置
       RequestMatcher authorizationServerEndpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
   
       // 拦截 授权服务器相关的请求端点
       http.requestMatcher(authorizationServerEndpointsMatcher)
               .authorizeRequests().anyRequest().authenticated().and()
               // 忽略掉相关端点的csrf
               .csrf(csrf -> csrf.ignoringRequestMatchers(authorizationServerEndpointsMatcher))
               // 开启form登录
               .formLogin()
               .and()
               // 应用 授权服务器的配置
               .apply(authorizationServerConfigurer);
   }
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  12.
  13.
  14.
  15.
  16.
  17.
  你可以调用OAuth2AuthorizationServerConfigurer提供的配置方法进行一些个性化配置。
 
  OAuth2.0客户端信息持久化
  这些信息会持久化到数据库,Spring Authorization Server提供了三个DDL脚本。在入门教程的DEMO,H2会自动初始化执行这些DDL脚本,如果你切换到Mysql等数据库,可能需要你自行执行。
 
  客户端配置信息注册
 
  授权服务器要求客户端必须是已经注册的,避免非法的客户端发起授权申请。就像你平常去一些开放平台申请一个ClientID和Secret。下面是定义脚本:
 
  复制
  CREATE TABLE oauth2_registered_client
  (
      id                            varchar(100)                        NOT NULL,
      client_id                     varchar(100)                        NOT NULL,
      client_id_issued_at           timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
      client_secret                 varchar(200)                        NULL,
      client_secret_expires_at      timestamp                           NULL,
      client_name                   varchar(200)                        NOT NULL,
      client_authentication_methods varchar(1000)                       NOT NULL,
      authorization_grant_types     varchar(1000)                       NOT NULL,
      redirect_uris                 varchar(1000)                       NULL,
      scopes                        varchar(1000)                       NOT NULL,
      client_settings               varchar(2000)                       NOT NULL,
      token_settings                varchar(2000)                       NOT NULL,
      PRIMARY KEY (id)
  );
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  12.
  13.
  14.
  15.
  16.
  对应的Java类为RegisteredClient:
 
  复制
  public class RegisteredClient implements Serializable {
   private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
   private String id;
   private String clientId;
   private Instant clientIdIssuedAt;
   private String clientSecret;
   private Instant clientSecretExpiresAt;
   private String clientName;
   private Set<ClientAuthenticationMethod> clientAuthenticationMethods;
   private Set<AuthorizationGrantType> authorizationGrantTypes;
   private Set<String> redirectUris;
   private Set<String> scopes;
   private ClientSettings clientSettings;
   private TokenSettings tokenSettings;
       
      // 省略
  }
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  12.
  13.
  14.
  15.
  16.
  17.
  定义一个客户端可以通过下面的Builder方法实现:
 
  复制
         RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
  //               唯一的客户端ID和密码
                  .clientId("felord-client")
                  .clientSecret("secret")
  //                名称 可不定义
                  .clientName("felord")
  //                授权方法
                  .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
  //                授权类型
                  .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                  .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                  .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
  //                回调地址名单,不在此列将被拒绝 而且只能使用IP或者域名  不能使用 localhost
                  .redirectUri("http://127.0.0.1:8080/login/oauth2/code/felord-oidc")
                  .redirectUri("http://127.0.0.1:8080/authorized")
                  .redirectUri("http://127.0.0.1:8080/foo/bar")
                  .redirectUri("https://baidu.com")
  //                OIDC支持
                  .scope(OidcScopes.OPENID)
  //                其它Scope
                  .scope("message.read")
                  .scope("message.write")
  //                JWT的配置项 包括TTL  是否复用refreshToken等等
                  .tokenSettings(TokenSettings.builder().build())
  //                配置客户端相关的配置项,包括验证密钥或者 是否需要授权页面
                  .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                  .build();
  1.
  2.
  3.
  4.
  5.
  6.
  7.
  8.
  9.
  10.
  11.
  12.
  13.
  14.
  15.
  16.
  17.
  18.
  19.
  20.
  21.
  22.
  23.
  24.
  25.
  26.
  27.
  持久化到数据库的RegisteredClient用JSON表示为:
 
  复制
  {
    "id": "658cd010-4d8c-4824-a8c7-a86b642299af",
    "client_id": "felord-client",
    "client_id_issued_at": "2021-11-11 18:01:09",
    "client_secret": "{bcrypt}$2a$10$XKZ8iUckDcdQWnqw682zV.DVyGuov8Sywx1KyAn4tySsw.Jtltg0.",
    "client_secret_expires_at": null,
    "client_name": "felord",
    "client_authentication_methods": "client_secret_basic",
    "authorization_grant_types": "refresh_token,client_credentials,authorization_code",
    "redirect_uris": "http://127.0.0.1:8080/foo/bar,http://127.0.0.1:8080/authorized,http://127.0.0.1:8080/login/oauth2/code/felord-oidc,https://baidu.com",
    "scopes": "openid,message.read,message.write",
    "client_settings": "{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}",
    "token_settings": "{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300.000000000],"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000]}"
  }
   14.
  注意上面的配置和你OAuth2.0客户端应用的配置息息相关。
 
  既然持久化了,那自然需要操作该表的JDBC服务接口了,这个接口为RegisteredClientRepository。我们需要声明一个实现为Spring Bean,这里选择基于JDBC的实现:
 
  复制
  @Bean
  public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
       return new JdbcRegisteredClientRepository(jdbcTemplate);
    }
  1.
  2.
  3.
  4.
  别忘记调用save(RegisteredClient)方法把需要注册的客户端信息持久化。
 
  该实现依赖spring-boot-starter-jdbc类库,你也可以闲得慌使用Mybatis进行实现。

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读