Spring Security OAuth2 - 是否可以更改表名和列名?

时间:2018-01-29 17:17:28

标签: java spring spring-security oauth

我正在使用Spring Boot和Spring Security构建支持OAuth2的应用程序。最初,我使用了标注为here的架构。有了这个,我能够使应用程序至少运行。但是,我想让命名的数据库对象略有不同 - 特别是使用PascalCase而不是下划线。

例如,而不是

CREATE TABLE [dbo].[oauth_client_details](
    [client_id] [varchar](256) NOT NULL,
    [resource_ids] [varchar](256) NULL,
    [client_secret] [varchar](256) NULL,
    [scope] [varchar](256) NULL,
    [authorized_grant_types] [varchar](256) NULL,
    [web_server_redirect_uri] [varchar](256) NULL,
    [authorities] [varchar](256) NULL,
    [access_token_validity] [int] NULL,
    [refresh_token_validity] [int] NULL,
    [additional_information] [varchar](4096) NULL,
    [autoapprove] [varchar](256) NULL,
PRIMARY KEY CLUSTERED 
(
    [client_id] ASC
)

我想:

CREATE TABLE [dbo].[OAuthClientDetails](
    [ClientID] [nvarchar](256) NOT NULL,
    [ResourceIDs] [nvarchar](256) NULL,
    [ClientSecret] [nvarchar](256) NOT NULL,
    [Scope] [nvarchar](256) NULL,
    [AuthorizedGrantTypes] [nvarchar](256) NOT NULL,
    [AccessTokenValidity] [int] NULL,
    [RefreshTokenValidity] [int] NULL,
 CONSTRAINT [PK_OAuthClientDetails] PRIMARY KEY CLUSTERED 
(
    [ClientID] ASC
)

我不赞成如何(或者如果可能)超越这些期望。例如,当我尝试使用PascalCase数据库时,它仍然期望原始的命名风格。请求令牌时收到以下内容:

"message": "PreparedStatementCallback; bad SQL grammar [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'oauth_client_details'.",
"path": "/oauth/token"

我的AuthServerConfig:

 @EnableAuthorizationServer


 @Configuration
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter{
    @Autowired
    private TokenStore tokenStore;

@Autowired
private AccessTokenConverter converter;

 private final AppConfig appConfig; 

private AuthenticationManager authenticationManager;

@Autowired
public AuthServerConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
    this.authenticationManager = authenticationManager;
    this.appConfig = appConfig;
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.checkTokenAccess("permitAll()");
    security.tokenKeyAccess("permitAll()");
}

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


    configurer.jdbc(appConfig.dataSource());
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    endpoints.tokenStore(tokenStore)
            .accessTokenConverter(converter)
        .authenticationManager(authenticationManager);
}



   @Bean
   @Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
   public DefaultTokenServices tokenServices() {
      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
      defaultTokenServices.setTokenStore(tokenStore);
      defaultTokenServices.setSupportRefreshToken(true);
      return defaultTokenServices;
   }       

我的AppConfig课程:

@Configuration
public class AppConfig {


    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Value("${spring.datasource.driverClassName}")
    private String dbDriverClassName;

    @Value("${spring.datasource.username}")
    private String dbUsername;

    @Value("${spring.datasource.password}")
    private String dbPassword;

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

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(dbDriverClassName);
        dataSource.setUrl(datasourceUrl);
        dataSource.setUsername(dbUsername);
        dataSource.setPassword(dbPassword);

        return dataSource;
    }    

    // Reference: http://www.baeldung.com/spring-security-oauth-jwt

    /* !!!!!!!!!!!!!!!!!!!!!!!!!! 
    ** TODO 
    * Secure key file for deployment.
    !!!!!!!!!!!!!!!!!!!! */
       @Bean
       public JwtAccessTokenConverter accessTokenConverter() {
          JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
          KeyStoreKeyFactory keyStoreKeyFactory = 
                  new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
                converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
          return converter;
       }


       @Bean
       public TokenStore tokenStore() {
          return new JwtTokenStore(accessTokenConverter());
       }

根据Spring Security OAuth Documentation

NOTE: the schema for the JDBC service is not packaged with the library (because there are too many variations you might like to use in practice), but there is an example you can start from in the test code in github.

但是,似乎确实对结构做了一些假设。例如,我从未明确地告诉过#34;应用程序使用名为o_auth_client_details的表。

任何指导都将不胜感激。感谢。

2 个答案:

答案 0 :(得分:2)

您可以自定义JdbcClientDetailsService,请参阅

并将其添加到您的配置器,请参阅ClientDetailsServiceConfigurer#withClientDetails

  

<强> withClientDetails

     
public ClientDetailsServiceBuilder<?> withClientDetails(ClientDetailsService clientDetailsService) throws Exception 

您修改过的代码:

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

     JdbcClientDetailsService clientDetailsService= new JdbcClientDetailsService(appConfig.dataSource()); 
     clientDetailsService.setDeleteClientDetailsSql(myDeleteClientDetailsSql);
     clientDetailsService.setFindClientDetailsSql(myFindClientDetailsSql); 
     clientDetailsService.setInsertClientDetailsSql(myInsertClientDetailsSql); 
     clientDetailsService.setInsertClientDetailsSql(myInsertClientDetailsSql); 
     clientDetailsService.setSelectClientDetailsSql(mySelectClientDetailsSql); 
     clientDetailsService.setUpdateClientDetailsSql(myUpdateClientDetailsSql); 
     clientDetailsService.setUpdateClientSecretSql(myUpdateClientSecretSql); 

     configurer.withClientDetails(clientDetailsService);
}

答案 1 :(得分:-1)

非常简单。 请按照下列步骤操作:

    从oauth2 jar文件或用户中的
  1. 在此类的 spring-security.xml 配置文件中找到 JdbcClientDetailsS​​ervice JdbcTokenStore
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStor*">
     <constructor-arg ref="dataSource" />
</bean>
  1. 制作每个类的副本,然后在程序中创建一个新类。然后将表和列的名称更改为适当的名称(我更改表和列的名称)。
public class CustomeJdbcTokenStore implements TokenStore { 
    private String insertAccessTokenSql = "insert oauthAccessToken
        (tokenId, token, authenticationId, username, clientId, authentication, refreshToken) 
        values (?, ?, ?, ?, ?, ?, ?)";

    private String selectAccessTokenSql = "select tokenId, token from 
         oauthAccessToken where tokenId = ?";

    private String selectAccessTokenAuthenticationSql = "select tokenId, authentication from 
         oauthAccessToken where tokenId = ?";
  1. 将新类添加到 spring-security.xml 文件。
<bean id="tokenStore" class="ir.hossein.irtms.service.CustomJdbcTokenStore**">
     <constructor-arg ref="dataSource" />
</bean>