0

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 が定義されていません

4

1 に答える 1

1

特に答えを探し始めてからしばらく時間が経ち、ここに投稿したばかりの場合は特に、答えがどこからともなく出てくるので面白いです。しかたがない。

ここでランダムに見つかったコード スニペットによると、XML 構成ファイルからその行をコメント アウトするだけでよかったようです。

<!--   <oauth:token-services id="tokenServices"/> -->

これを次のものに置き換えます。

<beans:bean id="tokenServices" class="experiments.DatabaseProviderTokenServices" />

クラスはもちろん私の実装です。これにより、デフォルトの InMemoryProviderTokenServices クラスの代わりに DatabaseProviderTokenServices クラスが使用されます。

于 2013-08-27T16:03:09.793 に答える