Skip to content

Add ability to change client secret #531

Closed
@GrmpfNarf

Description

@GrmpfNarf

Expected Behavior
The RegisteredClientRepository should have the ability to change the client secret of an existing client.

Current Behavior
In version 0.2.1 the ability was removed because in prior versions the secret was encoded twice. The Bug and PR are reported in issue #389.

Context
I have a adminstration UI for the clients where it should be possible to edit the secret without deleting and adding the client again especially because there is no delete method on default.

Solution Proposal
The following is a proposal of my solution which is based on the "old" authroization server where changing the client secret is an extra method.

public class CustomJdbcRegisteredClientRepository extends JdbcRegisteredClientRepository {

    private final PasswordEncoder passwordEncoder;

    private static final String TABLE_NAME = "oauth2_registered_client";

    private static final String PK_FILTER = "id = ?";

    // @formatter:off
    private static final String UPDATE_REGISTERED_CLIENT_CLIENT_SECRET_SQL = "UPDATE " + TABLE_NAME
            + " SET client_secret = ?, client_secret_expires_at = ?,"
            + " WHERE " + PK_FILTER;
    // @formatter:on

    public CustomJdbcRegisteredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
        super(jdbcOperations);
        this.passwordEncoder = passwordEncoder;
    }

    public void updateRegisteredClientClientSecret(String newClientSecret, Instant newClientSecretExpiresAt, String id) {
        Timestamp clientSecretExpiresAt = newClientSecretExpiresAt != null ?
                Timestamp.from(newClientSecretExpiresAt) : null;

        String encodedClientSecret = passwordEncoder.encode(newClientSecret);

        List<SqlParameterValue> parameters = Arrays.asList(
                new SqlParameterValue(Types.VARCHAR, encodedClientSecret),
                new SqlParameterValue(Types.TIMESTAMP, clientSecretExpiresAt),
                new SqlParameterValue(Types.VARCHAR, id)
        );
        PreparedStatementSetter pss = new ArgumentPreparedStatementSetter(parameters.toArray());
        getJdbcOperations().update(UPDATE_REGISTERED_CLIENT_CLIENT_SECRET_SQL, pss);
    }
}

As you can see the secret will be encoded in this solution. If its already encoded it will be encoded twice. But, because this is an extra method the calling method can decide to not call it.

Example of usage:

private final CustomJdbcRegisteredClientRepository clientRegistrationService;

...

public void updateClient(RegisteredClient updatedClient) {
    clientRegistrationService.save(updatedClient);

    RegisteredClient existingRegisteredClient = clientRegistrationService.findByClientId(updatedClient.getClientId()));

    if (!Objects.equals(updatedClient.getClientSecret(), existingRegisteredClient.getClientSecret())) {
        clientRegistrationService.updateRegisteredClientClientSecret(updatedClient.getClientSecret(), null, existingRegisteredClient.getId());
    }
}

Whould be nice if something like that will be in one of the further implementations.

Metadata

Metadata

Assignees

Labels

status: declinedA suggestion or change that we don't feel we should currently apply

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions