複数のOauth2アクセストークン


13

oAuth2を使用するAPIと、このAPIをバックエンドとして使用する独自のモバイルアプリがあります。ユーザーは複数のデバイス(iPhone、iPad、Androidタブレット、Androidフォンなど)を介して同時にログオンできるため、各接続を区別するAPIが必要です。個別のアクセストークンを介してこれを実行したいです。各クライアントは個別のアクセストークンを取得します。

問題は、現在使用している実装(spring-security-oauth2)がclient_id、ユーザー名、スコープに基づいて一意のキーを生成することです。したがって、基本的に、アクセストークンを取得すると、すべてのクライアントは同じユーザーに対して同じアクセストークンを取得します。これは、DefaultAuthenticationKeyGeneratorを使用して行われます。

認証キージェネレーターを無視して、クライアントからのリクエストごとに新しいアクセストークンを作成するだけで安全ですか?


2
スコープを使用して各クライアントを区別できますか?すなわち、iosに「ios」スコープ、androidに「android」スコープ、タブレットに「tablet」スコープなどを指定します。毎回新しいトークンを生成しました。
ロブ

ただし、一般に、Spring Security OAuth2実装は(XML構成を取得したら)私にとってはうまく機能しましたが、トークンと認証オブジェクトの管理は継続的な問題でした。
ロブ

2
Googleで「DefaultAuthenticationKeyGenerator」を検索すると、GitHubのspring-security-oauthライブラリにある.javaファイルが見つかりました。そのクラスはAuthenticationKeyGeneratorインターフェースを実装します。独自の実装を作成し、代わりに使用できますか?
グレッグブルクハート


2
「アンドロイド」、「ios」、「ウェブ」などのリクエストでdevicetypeを使用できる@Robに同意します
Vikash Rajpurohit

回答:


1

Springクラウドはすでにこの動作を提供しています。異なるクライアントを追加するだけです。iosAppClientと同様に、AuthorizationServerConfigurationクラスのandroidAppClient。

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                clients.inMemory().withClient("androidAppclient")
                    .secret("clientsecret")
                    .autoApprove(true)
                    .accessTokenValiditySeconds(120)
                    .authorizedGrantTypes("password")
                    .resourceIds("accountservice")
                    .scopes("read", "write")
                    .and()
                    .withClient("iosappclient")
                    ........

        }

バックエンドでは、次のようなclientIDを取得できます

clientId = ((OAuth2Authentication) authentication).getOAuth2Request().getClientId();

clientIdに基づいて異なる動作を実装します。


0

1つの答えは、各アプリプラットフォームが異なるクライアントであるため、異なるクライアントIDを持つ必要があるということです。iOSアプリ用、Webサイト用など。

iPadとiPhoneを区別することに関しては、OAuthシステムに依存しないことをお勧めします。


0

Spring BootとOAuth2でバックエンドを開発しているときに、同じ問題に出くわしました。私が遭遇した問題は、複数のデバイスが同じトークンを共有する場合、1つのデバイスがトークンを更新すると、他のデバイスは無知になり、要するに、両方のデバイスがトークンを更新するという狂気になります。私の解決策は、デフォルトAuthenticationKeyGeneratorをキージェネレーター混合のDefaultAuthenticationKeyGenerator新しいパラメーターをオーバーライドして追加するカスタム実装で置き換えることでしたclient_instance_id。モバイルクライアントは、アプリのインストール(iOSまたはAndroid)全体で一意である必要があるこのパラメーターを送信します。ほとんどのモバイルアプリは既に何らかの形でアプリケーションインスタンスを追跡しているため、これは特別な要件ではありません。

public class EnhancedAuthenticationKeyGenerator extends DefaultAuthenticationKeyGenerator {

    public static final String PARAM_CLIENT_INSTANCE_ID = "client_instance_id";

    private static final String KEY_SUPER_KEY = "super_key";
    private static final String KEY_CLIENT_INSTANCE_ID = PARAM_CLIENT_INSTANCE_ID;

    @Override
    public String extractKey(final OAuth2Authentication authentication) {
        final String superKey = super.extractKey(authentication);

        final OAuth2Request authorizationRequest = authentication.getOAuth2Request();
        final Map<String, String> requestParameters = authorizationRequest.getRequestParameters();

        final String clientInstanceId = requestParameters != null ? requestParameters.get(PARAM_CLIENT_INSTANCE_ID) : null;
        if (clientInstanceId == null || clientInstanceId.length() == 0) {
            return superKey;
        }

        final Map<String, String> values = new LinkedHashMap<>(2);
        values.put(KEY_SUPER_KEY, superKey);
        values.put(KEY_CLIENT_INSTANCE_ID, clientInstanceId);

        return generateKey(values);
    }

}

同様の方法で注入します:

final JdbcTokenStore tokenStore = new JdbcTokenStore(mDataSource);
tokenStore.setAuthenticationKeyGenerator(new EnhancedAuthenticationKeyGenerator());

HTTPリクエストは次のようになります

POST /oauth/token HTTP/1.1
Host: {{host}}
Authorization: Basic {{auth_client_basic}}
Content-Type: application/x-www-form-urlencoded

grant_type=password&username={{username}}&password={{password}}&client_instance_id={{instance_id}}

このアプローチを使用する利点は、クライアントがを送信しない場合、client_instance_idデフォルトのキーが生成され、インスタンスが提供される場合、同じインスタンスに対して毎回同じキーが返されることです。また、キーはプラットフォームに依存しません。欠点は、MD5ダイジェスト(内部で使用)が2回呼び出されることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.