Birden çok Oauth2 erişim jetonu


13

Ben oAuth2 kullanan bir API ve arka uç olarak bu API kullanan kendi mobil uygulamalarım var. Kullanıcılar aynı anda birden fazla cihazla (yani iPhone, iPad, android tablet veya android telefon) oturum açabildiğinden, her bağlantıyı ayırt etmek için API'ye ihtiyacım var. Bunu ayrı erişim belirteçleri aracılığıyla yapmak istiyorum: her istemci ayrı bir erişim belirteci alır.

Sorun şu an kullandığımız uygulamanın (spring-security-oauth2) client_id, kullanıcı adı ve kapsamı temelinde benzersiz bir anahtar oluşturmasıdır. Temel olarak, bir erişim belirteci alırken, tüm istemciler aynı kullanıcı için aynı erişim belirtecini alır. Bu, DefaultAuthenticationKeyGenerator kullanılarak yapılır.

Kimlik doğrulama anahtarı oluşturucusunu yok saymak ve istemciden gelen her istekte yeni bir erişim belirteci oluşturmak güvenli midir?


2
her müşteriyi farklılaştırmak için kapsam kullanabilir misiniz? yani ios bir "ios" kapsamı vermek, android bir "android" kapsamı, tablet bir "tablet" kapsamı, vb. Ama FWIW Ben kendi TokenServices uygulama yazma aslında (aslında ben varsayılan etrafında bir sarıcı yaptı düşünüyorum) ki her seferinde yepyeni bir jeton oluşturdu.
Rob

Genel olarak, Spring Security OAuth2 uygulaması benim için iyi çalıştı (XML yapılandırmasını geçtikten sonra), ancak belirteç ve kimlik doğrulama nesnelerini yönetmek devam eden bir acı noktasıydı.
Rob

2
Google'da "DefaultAuthenticationKeyGenerator" araması beni GitHub'daki spring-security-oauth kütüphanesinde bir .java dosyasına yönlendirdi. Bu sınıf AuthenticationKeyGeneratorarabirimi uygular . Kendi uygulamanızı oluşturabilir ve bunu kullanabilir misiniz?
Greg Burghardt


2
@Rob ile katılıyorum "android", "ios", "web" vb gibi
istekte devicetype ile gidebilirsiniz

Yanıtlar:


1

Bahar bulutu zaten bu davranışı sağlar. Sadece farklı Müşteriler ekleyin. İosAppClient gibi, AuthorizationServerConfiguration sınıfınızdaki 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")
                    ........

        }

Arka uçta clientID'yi aşağıdaki gibi alabilirsiniz

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

ve clientId tabanlı farklı davranışlar uygulamak.


0

Yanıtlardan biri, her uygulama platformunun farklı bir istemcidir, bu nedenle farklı bir istemci kimliğine sahip olması gerekir. Biri iOS uygulaması için, biri web sitesi için, vb.

IPad ve iPhone arasında bir ayrım yapmak gelince, bunun için OAuth sistemine güvenmemeyi öneririm.


0

Spring Boot ve OAuth2 ile arka ucumu geliştirirken aynı sorun üzerinde tökezledim. Karşılaştığım sorun, birden fazla cihaz aynı jetonları paylaşırsa, bir cihaz jetonu yenilediğinde, diğer cihaz clueless ve uzun hikaye kısa olacaktı, her iki cihazın da jeton yenileme çılgınlığına girdi. Çözümüm, varsayılanı , anahtar üreteci karışımına AuthenticationKeyGeneratorgeçersiz kılan DefaultAuthenticationKeyGeneratorve yeni bir parametre ekleyen özel bir uygulama ile değiştirmekti client_instance_id. Mobil istemcilerim daha sonra uygulama yüklemelerinde (iOS veya Android) benzersiz olması gereken bu parametreyi gönderir. Çoğu mobil uygulama zaten uygulama örneğini bir biçimde izlediğinden bu özel bir gereklilik değildir.

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

}

daha sonra benzer bir şekilde enjekte edersiniz:

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

HTTP isteği daha sonra şöyle görünecektir

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}}

Bu yaklaşımı kullanmanın yararı, istemci bir gönderme yapmazsa client_instance_id, varsayılan anahtarın üretilmesidir ve bir örnek sağlanırsa, aynı anahtar için her seferinde aynı anahtar döndürülür. Ayrıca, anahtar platformdan bağımsızdır. Dezavantajı, MD5 özetinin (dahili olarak kullanılır) iki kez çağrılmasıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.