Spring-security-oauth2的版本是2.0。
如下List-1所示
List-1
package org.springframework.security.oauth2.provider;
/**
* A service that provides the details about an OAuth2 client.
*
* @author Ryan Heaton
*/
public interface ClientDetailsService {
/**
* Load a client by the client id. This method must not return null.
*
* @param clientId The client id.
* @return The client details (never null).
* @throws ClientRegistrationException If the client account is locked, expired, disabled, or invalid for any other reason.
*/
ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException;
}
ClientDetailsService的实现类有InMemoryClientDetailsService和JdbcClientDetailsService。
List-2 InMemoryClientDetailsService
package org.springframework.security.oauth2.provider.client;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.NoSuchClientException;
/**
* Basic, in-memory implementation of the client details service.
*
* @author Ryan Heaton
*/
public class InMemoryClientDetailsService implements ClientDetailsService {
private Map<String, ClientDetails> clientDetailsStore = new HashMap<String, ClientDetails>();
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
ClientDetails details = clientDetailsStore.get(clientId);
if (details == null) {
throw new NoSuchClientException("No client with requested id: " + clientId);
}
return details;
}
public void setClientDetailsStore(Map<String, ? extends ClientDetails> clientDetailsStore) {
this.clientDetailsStore = new HashMap<String, ClientDetails>(clientDetailsStore);
}
}
InMemoryClientDetailsService如List-2所示,将ClientDetails存储到Hashmap中。
JdbcClientDetailsService则是将ClientDetails存储在数据库中,如下List-3所示
List-3 JdbcClientDetailsService的loadClientByClientId
public ClientDetails loadClientByClientId(String clientId) throws InvalidClientException {
ClientDetails details;
try {
details = jdbcTemplate.queryForObject(selectClientDetailsSql, new ClientDetailsRowMapper(), clientId);
}
catch (EmptyResultDataAccessException e) {
throw new NoSuchClientException("No client with requested id: " + clientId);
}
return details;
}
如List-3,用jdbcTemplate从数据库中查询,来看下selectClientDetailsSql,如下List-4
List-4
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 = ?
来看下ClientDetailsRowMapper,如下List-5,最终返回的是BaseClientDetails。
List-5
private static class ClientDetailsRowMapper implements RowMapper<ClientDetails> {
private JsonMapper mapper = createJsonMapper();
public ClientDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
BaseClientDetails details = new BaseClientDetails(rs.getString(1), rs.getString(3), rs.getString(4),
rs.getString(5), rs.getString(7), rs.getString(6));
details.setClientSecret(rs.getString(2));
if (rs.getObject(8) != null) {
details.setAccessTokenValiditySeconds(rs.getInt(8));
}
if (rs.getObject(9) != null) {
details.setRefreshTokenValiditySeconds(rs.getInt(9));
}
String json = rs.getString(10);
if (json != null) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> additionalInformation = mapper.read(json, Map.class);
details.setAdditionalInformation(additionalInformation);
}
catch (Exception e) {
logger.warn("Could not decode JSON for additional information: " + details, e);
}
}
String scopes = rs.getString(11);
if (scopes != null) {
details.setAutoApproveScopes(StringUtils.commaDelimitedListToSet(scopes));
}
return details;
}
}
(adsbygoogle = window.adsbygoogle || []).push({});