如何在Spring中使用JDBC为ClientDetailsS​​erviceConfigurer添加客户端?

Wim*_*uwe 13 java mysql spring-security-oauth2

我记忆中的事情如下:

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory()
               .withClient("clientapp")
               .authorizedGrantTypes("password", "refresh_token")
               .authorities("USER")
               .scopes("read", "write")
               .resourceIds(RESOURCE_ID)
               .secret("123456");
}
Run Code Online (Sandbox Code Playgroud)

我想使用JDBC实现.为此,我创建了以下表(使用MySQL):

-- Tables for OAuth token store

CREATE TABLE oauth_client_details (
  client_id               VARCHAR(255) PRIMARY KEY,
  resource_ids            VARCHAR(255),
  client_secret           VARCHAR(255),
  scope                   VARCHAR(255),
  authorized_grant_types  VARCHAR(255),
  web_server_redirect_uri VARCHAR(255),
  authorities             VARCHAR(255),
  access_token_validity   INTEGER,
  refresh_token_validity  INTEGER,
  additional_information  VARCHAR(4096),
  autoapprove             TINYINT
);

CREATE TABLE oauth_client_token (
  token_id          VARCHAR(255),
  token             BLOB,
  authentication_id VARCHAR(255),
  user_name         VARCHAR(255),
  client_id         VARCHAR(255)
);

CREATE TABLE oauth_access_token (
  token_id          VARCHAR(255),
  token             BLOB,
  authentication_id VARCHAR(255),
  user_name         VARCHAR(255),
  client_id         VARCHAR(255),
  authentication    BLOB,
  refresh_token     VARCHAR(255)
);

CREATE TABLE oauth_refresh_token (
  token_id       VARCHAR(255),
  token          BLOB,
  authentication BLOB
);

CREATE TABLE oauth_code (
  code           VARCHAR(255),
  authentication BLOB
);
Run Code Online (Sandbox Code Playgroud)

我是否需要在MySQL表中手动添加客户端?

我试过这个:

clients.jdbc(dataSource).withClient("clientapp")
               .authorizedGrantTypes("password", "refresh_token")
               .authorities("USER")
               .scopes("read", "write")
               .resourceIds(RESOURCE_ID)
               .secret("123456");
Run Code Online (Sandbox Code Playgroud)

希望Spring能在好的表中插入正确的东西,但似乎并没有这样做.为什么你可以进一步追逐jdbc()

And*_*ver 11

请休息这一步:

  1. 将此schema.sql放在资源文件夹中,以便在启动服务器后由SpringBoot检测到.如果你不使用spring boot,不用担心只从任何Mysql App Client导入这个脚本(phpmyadmin,HeidiSQL,Navicat ..)

    drop table if exists oauth_client_details; create table oauth_client_details ( client_id VARCHAR(255) PRIMARY KEY, resource_ids VARCHAR(255), client_secret VARCHAR(255), scope VARCHAR(255), authorized_grant_types VARCHAR(255), web_server_redirect_uri VARCHAR(255), authorities VARCHAR(255), access_token_validity INTEGER, refresh_token_validity INTEGER, additional_information VARCHAR(4096), autoapprove VARCHAR(255) ); drop table if exists oauth_client_token; create table oauth_client_token ( token_id VARCHAR(255), token LONG VARBINARY, authentication_id VARCHAR(255) PRIMARY KEY, user_name VARCHAR(255), client_id VARCHAR(255) ); drop table if exists oauth_access_token; create table oauth_access_token ( token_id VARCHAR(255), token LONG VARBINARY, authentication_id VARCHAR(255) PRIMARY KEY, user_name VARCHAR(255), client_id VARCHAR(255), authentication LONG VARBINARY, refresh_token VARCHAR(255) ); drop table if exists oauth_refresh_token; create table oauth_refresh_token ( token_id VARCHAR(255), token LONG VARBINARY, authentication LONG VARBINARY ); drop table if exists oauth_code; create table oauth_code ( code VARCHAR(255), authentication LONG VARBINARY ); drop table if exists oauth_approvals; create table oauth_approvals ( userId VARCHAR(255), clientId VARCHAR(255), scope VARCHAR(255), status VARCHAR(10), expiresAt TIMESTAMP, lastModifiedAt TIMESTAMP ); drop table if exists ClientDetails; create table ClientDetails ( appId VARCHAR(255) PRIMARY KEY, resourceIds VARCHAR(255), appSecret VARCHAR(255), scope VARCHAR(255), grantTypes VARCHAR(255), redirectUrl VARCHAR(255), authorities VARCHAR(255), access_token_validity INTEGER, refresh_token_validity INTEGER, additionalInformation VARCHAR(4096), autoApproveScopes VARCHAR(255) );
  2. 在OthorizationServer中注入DataSource,authenticationManager,UserDetailsS​​ervice

    @Autowired private MyUserDetailsService userDetailsService; @Inject private AuthenticationManager authenticationManager; @Autowired private DataSource dataSource;
  3. 您将需要创建这两个bean

    @Bean public JdbcTokenStore tokenStore() { return new JdbcTokenStore(dataSource); } @Bean protected AuthorizationCodeServices authorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); }

    请不要忘记AuthorizationServer类顶部的@Configuration

  4. 配置要在mysql数据库中创建的客户端应用程序: clients.jdbc(dataSource).withClient("clientapp") .authorizedGrantTypes("password", "refresh_token") .authorities("USER") .scopes("read", "write") .resourceIds(RESOURCE_ID) .secret("123456");

    你已经完成了这件事.

  5. 最重要的事情(我认为你忘了它..)是:使用AuthorizationServerEndpointsConfigurer配置你的端点:

    endpoints.userDetailsService(userDetailsService) .authorizationCodeServices(authorizationCodeServices()).authenticationManager(this.authenticationManager).tokenStore(tokenStore()).approvalStoreDisabled();

这就是男人,现在它应该工作;)

随时可以要求更多...我很乐意提供帮助

我已经发送了一条来自tweeter的消息!

  • 我将项目上传到这里,https://github.com/warunacds/spring-auth-test.git,数据库模式也可​​用。谢谢 (2认同)

小智 10

这个问题相当陈旧,但没有一个回复回答了提问者的原始问题.我偶然发现了同样的问题,同时让我熟悉了spring的oauth2实现,并想知道为什么ClientDetailsServiceConfigurer不能通过JdbcClientDetailsServiceBuilder(通过调用jdbc(datasource)configurer上的方法实例化)以编程方式添加的客户端,尽管所有的教程都在net显示了一个类似的例子,例如Wim发布的例子.在深入挖掘代码后,我注意到了原因.好吧,这只是因为oauth_clients_details永远不会调用更新表的代码.配置所有客户端后,缺少的是以下调用:.and().build().所以,Wim的代码实际上必须如下所示:

clients.jdbc(dataSource).withClient("clientapp")
           .authorizedGrantTypes("password", "refresh_token")
           .authorities("USER")
           .scopes("read", "write")
           .resourceIds(RESOURCE_ID)
           .secret("123456").and().build();
Run Code Online (Sandbox Code Playgroud)

瞧,客户端clientapp现在已经存入数据库.

  • 谢谢你的答案,它的确有效.但是,在每次启动应用程序时,它都会尝试在oauth_client_details表中插入一个条目,这会导致重复的条目错误.有没有办法只建一次? (3认同)