Spring-security-oauth を使用して RESTful アプリケーションを保護しています。データベースにトークンを保存するために、カスタム OAuthProviderTokenServices クラスを実装しようとしています。ドキュメントから得たのは次のとおりです。
OAuthProviderTokenServices 実装を作成する場合、ランダム値を介してトークンを作成し、トークンの永続性以外のすべてを処理する RandomValueProviderTokenServices の拡張を検討することをお勧めします。適切な OAuthProviderTokenServices のメモリ内実装もあります [...]
これで問題ないので、新しいカスタム クラスを作成しました。
package experiments;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenImpl;
import org.springframework.security.oauth.provider.token.RandomValueProviderTokenServices;
/**
* Implementation of TokenServices that stores tokens in a database.
*
* @author Seether
*/
public class DatabaseProviderTokenServices extends RandomValueProviderTokenServices {
protected final ConcurrentHashMap<String, OAuthProviderTokenImpl> tokenStore = new ConcurrentHashMap<String, OAuthProviderTokenImpl>();
protected OAuthProviderTokenImpl readToken(String token) {
return tokenStore.get(token);
}
protected void storeToken(String tokenValue, OAuthProviderTokenImpl token) {
tokenStore.put(tokenValue, token);
}
protected OAuthProviderTokenImpl removeToken(String tokenValue) {
return tokenStore.remove(tokenValue);
}
}
今のところ、ご覧のとおり、これは InMemoryProviderTokenServices クラスと同じです。
私のアプリケーションは、sparkl の例の AccessConfirmationController を使用します。これは次のとおりです。
package experiments;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.oauth.provider.ConsumerDetails;
import org.springframework.security.oauth.provider.ConsumerDetailsService;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenServices;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Controller for retrieving the model for and displaying the confirmation page for access to a protected resource.
*
* @author Ryan Heaton
*/
@Controller
public class AccessConfirmationController {
private OAuthProviderTokenServices tokenServices;
private ConsumerDetailsService consumerDetailsService;
@RequestMapping("/oauth/confirm_access")
public ModelAndView getAccessConfirmation(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String token = request.getParameter("oauth_token");
if (token == null) {
throw new IllegalArgumentException("A request token to authorize must be provided.");
}
OAuthProviderToken providerToken = tokenServices.getToken(token);
ConsumerDetails consumer = consumerDetailsService
.loadConsumerByConsumerKey(providerToken.getConsumerKey());
String callback = request.getParameter("oauth_callback");
TreeMap<String, Object> model = new TreeMap<String, Object>();
model.put("oauth_token", token);
if (callback != null) {
model.put("oauth_callback", callback);
}
model.put("consumer", consumer);
return new ModelAndView("access_confirmation", model);
}
public void setTokenServices(OAuthProviderTokenServices tokenServices) {
this.tokenServices = tokenServices;
}
public void setConsumerDetailsService(ConsumerDetailsService consumerDetailsService) {
this.consumerDetailsService = consumerDetailsService;
}
}
問題は次のとおりです。アプリケーションに、デフォルトの実装ではなく、tokenServices 実装を使用するように指示するにはどうすればよいでしょうか (現時点では InMemoryProviderTokenServices であると信じています)。
私はコントローラーをいじってみましたが、いくつかの試みはすべて私を java.lang.IllegalStateExceptions に導きました。
また、構成 XML に次の行があることにも気付きました。
<oauth:token-services id="tokenServices"/>
関連するヘルプが読むように、これはパズルの重要な部分かもしれません:
プロバイダー トークン サービスのメモリ内実装を宣言および構成するための要素。
それを削除すると、次のようになります。
org.springframework.beans.factory.BeanCreationException: ServletContext リソース [/WEB-INF/mvc-dispatcher-servlet.xml] で定義された名前 'accessConfirmationController' を持つ Bean の作成中にエラーが発生しました: Bean プロパティの設定中に Bean 'tokenServices' への参照を解決できません 'トークンサービス'; ネストされた例外は org.springframework.beans.factory.NoSuchBeanDefinitionException: 'tokenServices' という名前の Bean が定義されていません