Java TokenStore MongoDB Spring OAuth2

Java TokenStore MongoDB Spring OAuth2,java,spring,mongodb,spring-security-oauth2,Java,Spring,Mongodb,Spring Security Oauth2,我正在尝试在MongoDB上创建令牌存储 我想在我的应用程序中使用当前的DB连接。 我使用了JdbcTokenStore并对其进行了转换,但我认为我做得不对,因为我无法@Autowired(它是空的)。 我猜这是因为该bean在Mongo连接bean之前启动。 是否对此进行了修复,或者我需要从头开始创建连接? 另外,@值(${spring.data.mongodb.host}”)也不起作用 如果有人已经在Mongo上编写了TokenStore,则最有帮助。 因为我想我以后也会有序列化问题 我正在

我正在尝试在MongoDB上创建令牌存储

我想在我的应用程序中使用当前的DB连接。 我使用了
JdbcTokenStore
并对其进行了转换,但我认为我做得不对,因为我无法
@Autowired
(它是空的)。 我猜这是因为该bean在Mongo连接bean之前启动。 是否对此进行了修复,或者我需要从头开始创建连接? 另外,
@值(${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);
}
}

@Autowired
@Value
字段为空,因为
MongoDBTokenStore
实际上不是bean。它是由
new
创建的,Spring对此一无所知。
@Component
注释
MongoDBTokenStore
类,或通过
@Bean
工厂方法创建它

另外,看看这个实现,我认为这正是您想要的

@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);
}
.
.
.
}