0

Android クライアント用の Spring サーバーを作成しようとしていて、基本認証を使用しています。次のようなコントローラーがあります。

@RequestMapping(value = "login", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody Message login(HttpSession session) {
    logger.info("Accessing protected resource sid:"+session.getId());
    return new Message(100, "Congratulations!", "You have logged in.");
}

@RequestMapping(value = "play", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody Message play(HttpSession session) {
    logger.info("Accessing protected play resource");
    return new Message(100, "Congratulations!", "Launching play.");
}

ログイン中にクライアントが認証されると、play の呼び出し中に再認証する必要がなくなります。

私のセキュリティ設定は次のとおりです。

 protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/signup","/about").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);

        // @formatter:on
    }

}

上記のセッションを有効にしようとしましたが、ログインと再生のリクエスト ハンドラーでセッション ID を出力しようとすると、認証でログインした後に異なる ID を取得します。HttpBasic セキュリティを使用しています。HttpBasic セキュリティでセッションを持つことは可能ですか? ステートレスであり、できないことを示しているように見えるいくつかの記事を読みました。回避策はありますか、それとも別のセキュリティ モデルに切り替える必要がありますか?

クライアントコード:

クライアント側では、ログインのために次のようにリクエストを送信します。

@Override
    protected Message doInBackground(Void... params) {
        //final String url = getString(R.string.base_uri) + "/getmessage";
        final String url = "http://10.0.2.2:8080/login";

        // Populate the HTTP Basic Authentitcation header with the username and password
        HttpAuthentication authHeader = new HttpBasicAuthentication(username, password);
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setAuthorization(authHeader);
        requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        // Create a new RestTemplate instance
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());

        try {               // Make the network request
            Log.d(TAG, url);
            ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(requestHeaders), Message.class);

            if(response.getBody().getId() == 100)
                login_success = true;
            return response.getBody();

「再生」のクライアント コードも同様に記述しようとしていますが、認証ヘッダーを渡す必要はありません。リクエストヘッダーにセッション関連のパラメーターを渡して、同じセッションの一部であることをサーバーに通知する必要があると思いますが、その方法がわかりません。

4

1 に答える 1

1

RestTemplateセッションとのステートフルな通信をアーカイブしようとしていますが、ステートレスな方法で動作しているため機能しません。ログインから次の呼び出しまで状態 (セッション ID) を保持しません。カスタムClientHttpRequestFactoryを設定するだけで、この作品を見ることができました(Androidではわかりません)。

状態との通信が必要な場合は、Apache HttpClient を見ることができます。HttpContextリクエスト間で再利用するa とともに使用することで、状態を保持します。

セッション ID を自分でいじる可能性はありますが、お勧めできません。

于 2015-01-08T19:18:00.537 に答える