Oauth2 - JDBC实现如何更改数据库表名

时间:2017-03-27 12:05:07

标签: java spring jdbc spring-security spring-security-oauth2

我已经在this link.之后使用Spring安全性实现了OAuth2现在有几个表具有以下名称 - oauth_client_details,oauth_code,oauth_client_token等。现在我需要做的是更改这些名称。带有前缀(如“security_”)。我怎么能这样做?

4 个答案:

答案 0 :(得分:1)

1)JdbcClientDetailsService实现ClientDetailsService,它在硬编码的JDBC PreparedStatements中使用oauth_client_details表。

2)JdbcClientTokenServices实现ClientTokenServices,它使用硬编码的JDBC PreparedStatements中的oauth_client_token表。

3)JdbcAuthorizationCodeServices实现AuthorizationCodeServices,它在硬编码的JDBC PreparedStatements中使用oauth_code表。

在您的Oauth2Config.javaSecurityConfig(无论您怎么称呼它)中,当您连接服务时,您可以使用您手持卡塞的自定义服务,该服务实现与服务相同的界面试图覆盖。

所以...如果您想将客户端令牌存储在名为security_oauth_tokens的表中,那么您可以实现自己的ClientTokenServices并将其连接到您的配置中。

以下是如何开始创建使用spring存储库的CustomClientTokenServices的粗略示例:

@Component
public class RepositoryClientTokenServices implements ClientTokenServices
{

    @Autowired
    TokenRepository repository;

    private ClientKeyGenerator keyGenerator = new DefaultClientKeyGenerator();

    @Override
    public OAuth2AccessToken getAccessToken(final OAuth2ProtectedResourceDetails resource, final Authentication authentication)
    {

        String accessToken = keyGenerator.extractKey(resource, authentication);
        TokenEntity tokenEntity = this.repository.findByAuthenticationId(accessToken);

        if (tokenEntity == null && LOG.isInfoEnabled())
        {
            LOG.debug("Failed to find access token for authentication " + authentication);
            return null;
        }

        return new DefaultOAuth2AccessToken(tokenEntity.getValue());
    }

    @Override
    public void saveAccessToken(final OAuth2ProtectedResourceDetails resource, final Authentication authentication, final OAuth2AccessToken accessToken)
    {
      //use the repository to save the token
    }

    @Override
    public void removeAccessToken(final OAuth2ProtectedResourceDetails resource, final Authentication authentication)
    {
      //use repository to remove the token
    }
}

但是!可能最简单的方法是创建一个CustomJDBCClientTokenServices,只需对表名进行查找/替换,如下所示:

@Component
public class CustomJdbcClientTokenServices implements ClientTokenServices {

    private static final Log LOG = LogFactory.getLog(JdbcClientTokenServices.class);

    private static final String DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT = "insert into security_oauth_client_token (token_id, token, authentication_id, user_name, client_id) values (?, ?, ?, ?, ?)";

    private static final String DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT = "select token_id, token from security_oauth_client_token where authentication_id = ?";

    private static final String DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT = "delete from security_oauth_client_token where authentication_id = ?";

    private String insertAccessTokenSql = DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT;

    private String selectAccessTokenSql = DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT;

    private String deleteAccessTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT;

    private ClientKeyGenerator keyGenerator = new DefaultClientKeyGenerator();

    private final JdbcTemplate jdbcTemplate;

    public CustomJdbcClientTokenServices(DataSource dataSource) {
        Assert.notNull(dataSource, "DataSource required");
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public void setClientKeyGenerator(ClientKeyGenerator keyGenerator) {
        this.keyGenerator = keyGenerator;
    }

    public OAuth2AccessToken getAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {

        OAuth2AccessToken accessToken = null;

        try {
            accessToken = jdbcTemplate.queryForObject(selectAccessTokenSql, new RowMapper<OAuth2AccessToken>() {
                public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return SerializationUtils.deserialize(rs.getBytes(2));
                }
            }, keyGenerator.extractKey(resource, authentication));
        }
        catch (EmptyResultDataAccessException e) {
            if (LOG.isInfoEnabled()) {
                LOG.debug("Failed to find access token for authentication " + authentication);
            }
        }

        return accessToken;
    }

    public void saveAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication,
                                OAuth2AccessToken accessToken) {
        removeAccessToken(resource, authentication);
        String name = authentication==null ? null : authentication.getName();
        jdbcTemplate.update(
                insertAccessTokenSql,
                new Object[] { accessToken.getValue(), new SqlLobValue(SerializationUtils.serialize(accessToken)),
                        keyGenerator.extractKey(resource, authentication), name,
                        resource.getClientId() }, new int[] { Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.VARCHAR,
                        Types.VARCHAR });
    }

    public void removeAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication) {
        jdbcTemplate.update(deleteAccessTokenSql, keyGenerator.extractKey(resource, authentication));
    }

    public void setInsertAccessTokenSql(String insertAccessTokenSql) {
        this.insertAccessTokenSql = insertAccessTokenSql;
    }

    public void setSelectAccessTokenSql(String selectAccessTokenSql) {
        this.selectAccessTokenSql = selectAccessTokenSql;
    }

    public void setDeleteAccessTokenSql(String deleteAccessTokenSql) {
        this.deleteAccessTokenSql = deleteAccessTokenSql;
    }

}

答案 1 :(得分:0)

因为这些名称在客户端和提供者类中是硬编码的:

"oauth_client_details"中的

org.springframework.security.oauth2.provider.client.JdbcClientDetailsService

"oauth_code"

中的

org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices "oauth_client_token"

中的

org.springframework.security.oauth2.client.token.JdbcClientTokenServices

等等,

您可能需要手动重写这些类并将它们绑定到您自己的客户端和提供程序类。

(虽然这看起来并不容易。)

答案 2 :(得分:0)

在此片段中创建JDBCTokenStore时:

<div class="col-md-2">
    <input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" />
</div>
<div class="col-md-2">
      <input id="reset" name="reset" type="text" placeholder="reset" style="display:none" />
</div>

您可以在返回对象之前为 User.update( { _id: newDrink.creator}, { $addToSet:{ caffeine_list: newDrink }}).exec(function (err, updatedrink){ if(err) { console.log(err); }else { res.status(201).json(updatedrink); } }) 必须向数据库发出的SQL查询设置不同的值。看看source code:您将看到每个查询使用的不同设置器。

答案 3 :(得分:0)

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

    从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>