我正在尝试使用 MongoDB
创建令牌存储我想在我的应用中使用当前的数据库连接。
我已经使用JdbcTokenStore
并将其转换但我认为我做错了,因为我无法@Autowired
(它为空)。
我想这是因为bean在Mongo连接bean之前启动。
是否有任何修复或我需要从头开始创建连接?
此外@Value("${spring.data.mongodb.host}")
无效....
如果有人已经在Mongo上编写了TokenStore,那么最有用。 因为我想我之后也会有序列化问题。
我附上了我不那么正常的代码,请指教。
import lombok.Getter;
import lombok.Setter;
public class MongoDBTokenStore implements TokenStore {
private static final Log LOG = LogFactory.getLog(MongoDBTokenStore.class);
private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
@Autowired
AccessTokenRepository accessTokenRepository;
@Autowired
RefreshTokenRepository refreshTokenRepository;
@Value("${spring.data.mongodb.uri}")
String mongo_uri;
@Value("${spring.data.mongodb.host}")
String mongo_host;
@Value("${spring.data.mongodb.database}")
String mongo_database;
@Value("${spring.data.mongodb.port}")
String mongo_port;
public MongoDBTokenStore() {
//MongoClient mongoClient = new MongoClient();
//Assert.notNull(mongoTemplate, "DataSource required");
}
public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
this.authenticationKeyGenerator = authenticationKeyGenerator;
}
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
OAuth2AccessToken accessToken = null;
String key = authenticationKeyGenerator.extractKey(authentication);
try {
AccessTockenElement element = accessTokenRepository.findByAuthenticationId(key);
accessToken = element.getOAuth2AccessToken();
}
catch (EmptyResultDataAccessException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to find access token for authentication " + authentication);
}
}
catch (IllegalArgumentException e) {
LOG.error("Could not extract access token for authentication " + authentication, e);
}
if (accessToken != null
&& !key.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) {
removeAccessToken(accessToken.getValue());
// Keep the store consistent (maybe the same user is represented by this authentication but the details have
// changed)
storeAccessToken(accessToken, authentication);
}
return accessToken;
}
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
String refreshToken = null;
if (token.getRefreshToken() != null) {
refreshToken = token.getRefreshToken().getValue();
}
if (readAccessToken(token.getValue())!=null) {
removeAccessToken(token.getValue());
}
AccessTockenElement element = new AccessTockenElement();
element.setTokenId(extractTokenKey(token.getValue()));
element.setOAuth2AccessToken(token);
element.setAuthenticationId(authenticationKeyGenerator.extractKey(authentication));
element.setUsername(authentication.isClientOnly() ? null : authentication.getName());
element.setClientId(authentication.getOAuth2Request().getClientId());
element.setOAuth2Authentication(authentication);
element.setRefreshToken(extractTokenKey(refreshToken));
accessTokenRepository.save(element);
}
public OAuth2AccessToken readAccessToken(String tokenValue) {
OAuth2AccessToken accessToken = null;
try {
AccessTockenElement element = accessTokenRepository.findByTokenId(extractTokenKey(tokenValue));
accessToken = element.getOAuth2AccessToken();
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for token " + tokenValue);
}
}
catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize access token for " + tokenValue, e);
removeAccessToken(tokenValue);
}
return accessToken;
}
public void removeAccessToken(OAuth2AccessToken token) {
removeAccessToken(token.getValue());
}
public void removeAccessToken(String tokenValue) {
accessTokenRepository.delete(extractTokenKey(tokenValue));
//jdbcTemplate.update(deleteAccessTokenSql, extractTokenKey(tokenValue));
}
public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
return readAuthentication(token.getValue());
}
public OAuth2Authentication readAuthentication(String token) {
OAuth2Authentication authentication = null;
try {
AccessTockenElement element = accessTokenRepository.findByTokenId(extractTokenKey(token));
authentication = element.getOAuth2Authentication();
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for token " + token);
}
}
catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize authentication for " + token, e);
removeAccessToken(token);
}
return authentication;
}
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
RefreshTockenElement element = new RefreshTockenElement();
element.setTokenId(extractTokenKey(refreshToken.getValue()));
element.setOAuth2RefreshToken(refreshToken);
element.setOAuth2Authentication(authentication);
refreshTokenRepository.save(element);
}
public OAuth2RefreshToken readRefreshToken(String token) {
OAuth2RefreshToken refreshToken = null;
try {
RefreshTockenElement element = refreshTokenRepository.findByTokenId(extractTokenKey(token));
refreshToken = element.getOAuth2RefreshToken();
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find refresh token for token " + token);
}
}
catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize refresh token for token " + token, e);
removeRefreshToken(token);
}
return refreshToken;
}
public void removeRefreshToken(OAuth2RefreshToken token) {
removeRefreshToken(token.getValue());
}
public void removeRefreshToken(String token) {
refreshTokenRepository.delete(extractTokenKey(token));
}
public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
return readAuthenticationForRefreshToken(token.getValue());
}
public OAuth2Authentication readAuthenticationForRefreshToken(String value) {
OAuth2Authentication authentication = null;
try {
RefreshTockenElement element = refreshTokenRepository.findByTokenId(extractTokenKey(value));
authentication = element.getOAuth2Authentication();
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for token " + value);
}
}
catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize access token for " + value, e);
removeRefreshToken(value);
}
return authentication;
}
public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
removeAccessTokenUsingRefreshToken(refreshToken.getValue());
}
public void removeAccessTokenUsingRefreshToken(String refreshToken) {
accessTokenRepository.deleteByRefreshToken(extractTokenKey(refreshToken));
}
public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>();
try {
List<AccessTockenElement> elements = accessTokenRepository.findByClientId(clientId);
for (AccessTockenElement element : elements) {
accessTokens.add(element.getOAuth2AccessToken());
}
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for clientId " + clientId);
}
}
accessTokens = removeNulls(accessTokens);
return accessTokens;
}
public Collection<OAuth2AccessToken> findTokensByUserName(String userName) {
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>();
try {
List<AccessTockenElement> elements = accessTokenRepository.findByUsername(userName);
for (AccessTockenElement element : elements) {
accessTokens.add(element.getOAuth2AccessToken());
}
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled())
LOG.info("Failed to find access token for userName " + userName);
}
accessTokens = removeNulls(accessTokens);
return accessTokens;
}
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>();
try {
List<AccessTockenElement> elements = accessTokenRepository.findByClientIdAndUsername(clientId, userName);
for (AccessTockenElement element : elements) {
accessTokens.add(element.getOAuth2AccessToken());
}
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for clientId " + clientId + " and userName " + userName);
}
}
accessTokens = removeNulls(accessTokens);
return accessTokens;
}
private List<OAuth2AccessToken> removeNulls(List<OAuth2AccessToken> accessTokens) {
List<OAuth2AccessToken> tokens = new ArrayList<OAuth2AccessToken>();
for (OAuth2AccessToken token : accessTokens) {
if (token != null) {
tokens.add(token);
}
}
return tokens;
}
protected String extractTokenKey(String value) {
if (value == null) {
return null;
}
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).");
}
try {
byte[] bytes = digest.digest(value.getBytes("UTF-8"));
return String.format("%032x", new BigInteger(1, bytes));
}
catch (UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 encoding not available. Fatal (should be in the JDK).");
}
}
protected byte[] serializeAccessToken(OAuth2AccessToken token) {
return SerializationUtils.serialize(token);
}
protected byte[] serializeRefreshToken(OAuth2RefreshToken token) {
return SerializationUtils.serialize(token);
}
protected byte[] serializeAuthentication(OAuth2Authentication authentication) {
return SerializationUtils.serialize(authentication);
}
protected OAuth2AccessToken deserializeAccessToken(byte[] token) {
return SerializationUtils.deserialize(token);
}
protected OAuth2RefreshToken deserializeRefreshToken(byte[] token) {
return SerializationUtils.deserialize(token);
}
protected OAuth2Authentication deserializeAuthentication(byte[] authentication) {
return SerializationUtils.deserialize(authentication);
}
@Document
@Setter
@Getter
class AccessTockenElement {
@Id
String tokenId;
OAuth2AccessToken OAuth2AccessToken;
@Indexed
String authenticationId;
@Indexed
String username;
@Indexed
String clientId;
OAuth2Authentication OAuth2Authentication;
@Indexed
String refreshToken;
}
@Document
@Setter
@Getter
class RefreshTockenElement {
@Id
String tokenId;
OAuth2RefreshToken OAuth2RefreshToken;
OAuth2Authentication OAuth2Authentication;
}
@RepositoryRestResource
interface AccessTokenRepository extends MongoRepository<AccessTockenElement, String> {
@Transactional
public AccessTockenElement findByTokenId(String tokenId);
@Transactional
public AccessTockenElement findByAuthenticationId(String tokenId);
@Transactional
public List<AccessTockenElement> findByClientId(String clientId);
@Transactional
public List<AccessTockenElement> findByUsername(String username);
@Transactional
public List<AccessTockenElement> findByClientIdAndUsername(String clientId, String username);
@Transactional
public void deleteByRefreshToken(String refreshTokenId);
}
@RepositoryRestResource
public interface RefreshTokenRepository extends MongoRepository<RefreshTockenElement, String> {
@Transactional
public RefreshTockenElement findByTokenId(String tokenId);
}
}
对TokenStore的调用是这样的:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore = new MongoDBTokenStore();
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private ExtendedUserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
}
.
.
.
}
答案 0 :(得分:3)
@Autowired
和@Value
字段为空,因为MongoDBTokenStore
实际上不是bean。它由new
创建,而Spring对此一无所知
使用MongoDBTokenStore
注释@Component
类,或按@Bean
工厂方法创建。
另外,请查看此实施MongoTokenStore,我认为这正是您正在寻找的。 p>