Dodawanie uwierzytelniania do aplikacji systemu Android

Podsumowanie

W tym samouczku dodasz uwierzytelnianie do projektu szybkiego startu listy todolist w systemie Android przy użyciu obsługiwanego dostawcy tożsamości. Ten samouczek jest oparty na Wprowadzenie samouczku Mobile Apps, który należy najpierw wykonać.

Rejestrowanie aplikacji w celu uwierzytelniania i konfigurowanie Azure App Service

Najpierw należy zarejestrować aplikację w witrynie dostawcy tożsamości, a następnie ustawić poświadczenia wygenerowane przez dostawcę w Mobile Apps back end.

  1. Skonfiguruj preferowanego dostawcę tożsamości, zgodnie z instrukcjami specyficznymi dla dostawcy:

  2. Powtórz poprzednie kroki dla każdego dostawcy, którego chcesz obsługiwać w aplikacji.

Dodawanie aplikacji do adresów URL dozwolonego zewnętrznego przekierowania

Bezpieczne uwierzytelnianie wymaga zdefiniowania nowego schematu adresu URL dla aplikacji. Dzięki temu system uwierzytelniania może przekierować z powrotem do aplikacji po zakończeniu procesu uwierzytelniania. W tym samouczku używamy nazwy aplikacji schematu adresu URL w całym. Możesz jednak użyć dowolnego schematu adresów URL, który wybierzesz. Powinna być unikatowa dla Twojej aplikacji mobilnej. Aby włączyć przekierowanie po stronie serwera:

  1. W Azure Portal wybierz swój App Service.

  2. Kliknij opcję menu Uwierzytelnianie/ autoryzacja.

  3. W adresie URL dozwolonego zewnętrznego przekierowania wprowadź .appname://easyauth.callback Nazwa aplikacji w tym ciągu to schemat adresu URL aplikacji mobilnej. Powinna być zgodne ze specyfikacją standardowego adresu URL dla protokołu (należy używać tylko liter i cyfr i rozpoczynać się literą). Należy zanotować ciąg, który wybierzesz, ponieważ konieczne będzie dostosowanie kodu aplikacji mobilnej za pomocą schematu adresu URL w kilku miejscach.

  4. Kliknij przycisk OK.

  5. Kliknij pozycję Zapisz.

Ograniczanie uprawnień do uwierzytelnionych użytkowników

Domyślnie interfejsy API w Mobile Apps mogą być wywoływane anonimowo. Następnie należy ograniczyć dostęp tylko do uwierzytelnionych klientów.

  • Node.js (za pośrednictwem Azure Portal):

    W ustawieniach Mobile Apps kliknij pozycję Łatwe tabele i wybierz tabelę. Kliknij pozycję Zmień uprawnienia, wybierz opcję Dostęp uwierzytelniony tylko dla wszystkich uprawnień, a następnie kliknij przycisk Zapisz.

  • .NET back end (C#):

    W projekcie serwera przejdź do plikówControllersTodoItemController.cs>. Dodaj atrybut [Authorize] do klasy TodoItemController w następujący sposób. Aby ograniczyć dostęp tylko do określonych metod, można również zastosować ten atrybut tylko do tych metod, a nie do klasy . Ponownie opublikować projekt serwera.

      [Authorize]
      public class TodoItemController : TableController<TodoItem>
    
  • Node.js zaplecza (za pośrednictwem Node.js kodu):

    Aby wymagać uwierzytelniania w celu uzyskania dostępu do tabeli, dodaj następujący wiersz do Node.js skryptu serwera:

      table.access = 'authenticated';
    

    Aby uzyskać więcej informacji, zobacz Uwierzytelnianie wymagane w celu uzyskania dostępu do tabel. Aby dowiedzieć się, jak pobrać projekt kodu szybkiego startu ze swojej witryny, zobacz How to: Download the Node.js backend quickstart code project using Git (Jak pobrać projekt kodu zaplecza przy użyciu usługi Git).

  • W Android Studio otwórz ukończony projekt za pomocą samouczka Wprowadzenie pomocą Mobile Apps. W menu Uruchom kliknij pozycję Uruchom aplikację i sprawdź, czy nieobsłużony wyjątek z kodem stanu 401 (Brak autoryzacji) jest wywoływany po uruchomieniu aplikacji.

    Ten wyjątek występuje, ponieważ aplikacja próbuje uzyskać dostęp do usługi back end jako nieuwierzytowany użytkownik, ale tabela TodoItem wymaga teraz uwierzytelniania.

Następnie zaktualizuj aplikację tak, aby uwierzytelniała użytkowników przed zażądaniem zasobów z Mobile Apps.

Dodawanie uwierzytelniania do aplikacji

  1. Otwórz projekt w Android Studio.

  2. W Project Explorer Android Studio otwórz plik ToDoActivity.java i dodaj następujące instrukcje importu:

    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.atomic.AtomicBoolean;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    
    import com.microsoft.windowsazure.mobileservices.authentication.MobileServiceAuthenticationProvider;
    import com.microsoft.windowsazure.mobileservices.authentication.MobileServiceUser;
    
  3. Dodaj następującą metodę do klasy ToDoActivity :

    // You can choose any unique number here to differentiate auth providers from each other. Note this is the same code at login() and onActivityResult().
    public static final int GOOGLE_LOGIN_REQUEST_CODE = 1;
    
    private void authenticate() {
        // Sign in using the Google provider.
        mClient.login(MobileServiceAuthenticationProvider.Google, "{url_scheme_of_your_app}", GOOGLE_LOGIN_REQUEST_CODE);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // When request completes
        if (resultCode == RESULT_OK) {
            // Check the request code matches the one we send in the login request
            if (requestCode == GOOGLE_LOGIN_REQUEST_CODE) {
                MobileServiceActivityResult result = mClient.onActivityResult(data);
                if (result.isLoggedIn()) {
                    // sign-in succeeded
                    createAndShowDialog(String.format("You are now signed in - %1$2s", mClient.getCurrentUser().getUserId()), "Success");
                    createTable();
                } else {
                    // sign-in failed, check the error message
                    String errorMessage = result.getErrorMessage();
                    createAndShowDialog(errorMessage, "Error");
                }
            }
        }
    }
    

    Ten kod tworzy metodę do obsługi procesu uwierzytelniania google. Zostanie wyświetlone okno dialogowe z identyfikatorem uwierzytelnionego użytkownika. Możesz przejść tylko po pomyślnym uwierzytelnieniu.

    Uwaga

    Jeśli używasz dostawcy tożsamości innego niż Google, zmień wartość przekazaną do metody logowania na jedną z następujących wartości: MicrosoftAccount, Facebook, Twitter lub windowsazureactivedirectory.

  4. W metodzie onCreate dodaj następujący wiersz kodu po kodzie, który inkrementuje obiekt MobileServiceClient .

    authenticate();
    

    To wywołanie rozpoczyna proces uwierzytelniania.

  5. Przenieś pozostały kod po w authenticate(); metodzie onCreate do nowej metody createTable :

    private void createTable() {
    
        // Get the table instance to use.
        mToDoTable = mClient.getTable(ToDoItem.class);
    
        mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
    
        // Create an adapter to bind the items with the view.
        mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
        ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
        listViewToDo.setAdapter(mAdapter);
    
        // Load the items from Azure.
        refreshItemsFromTable();
    }
    
  6. Aby upewnić się, że przekierowanie działa zgodnie z oczekiwaniami, dodaj następujący fragment kodu do RedirectUrlActivity :AndroidManifest.xml

    <activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="{url_scheme_of_your_app}"
                android:host="easyauth.callback"/>
        </intent-filter>
    </activity>
    
  7. Dodaj redirectUriScheme do build.gradle aplikacji systemu Android.

    android {
        buildTypes {
            release {
                // ...
                manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
            }
            debug {
                // ...
                manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
            }
        }
    }
    
  8. Dodaj com.android.support:customtabs:23.0.1 do zależności w swoim :build.gradle

    dependencies {
        // ...
        compile 'com.android.support:customtabs:23.0.1'
    }
    
  9. W menu Uruchom kliknij pozycję Uruchom aplikację , aby uruchomić aplikację i zalogować się przy użyciu wybranego dostawcy tożsamości.

Ostrzeżenie

W schemacie adresu URL, o którym wspomniano, jest zróżnicowana wielkość liter. Upewnij się, że wszystkie wystąpienia funkcji używają {url_scheme_of_you_app} tego samego przypadku.

Po pomyślnym zalogowaniu aplikacja powinna działać bez błędów i powinno być możliwe wykonywanie zapytań dotyczących usługi back-end i aktualizacja danych.

Buforowanie tokenów uwierzytelniania na kliencie

W poprzednim przykładzie po raz pierwszy zalogowano się, co wymaga od klienta skontaktowania się zarówno z dostawcą tożsamości, jak i z usługą platformy Azure za każdym razem, gdy aplikacja jest uruchamiana. Ta metoda jest nieefekcyjna i może mieć problemy związane z użyciem, jeśli wielu klientów spróbuje uruchomić aplikację jednocześnie. Lepszym rozwiązaniem jest buforowanie tokenu autoryzacji zwróconego przez usługę platformy Azure i próba użycia tego tokenu przed użyciem logowania opartego na dostawcy.

Uwaga

Możesz buforować token wystawiony przez usługę platformy Azure na zadomowieniu niezależnie od tego, czy używasz uwierzytelniania zarządzanego przez klienta, czy zarządzanego przez usługę. W tym samouczku jest używane uwierzytelnianie zarządzane przez usługę.

  1. Otwórz plik ToDoActivity.java i dodaj następujące instrukcje importu:

    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    
  2. Dodaj następujące składowe do ToDoActivity klasy .

    public static final String SHAREDPREFFILE = "temp";
    public static final String USERIDPREF = "uid";
    public static final String TOKENPREF = "tkn";
    
  3. W pliku ToDoActivity.java dodaj następującą definicję metody cacheUserToken .

    private void cacheUserToken(MobileServiceUser user)
    {
        SharedPreferences prefs = getSharedPreferences(SHAREDPREFFILE, Context.MODE_PRIVATE);
        Editor editor = prefs.edit();
        editor.putString(USERIDPREF, user.getUserId());
        editor.putString(TOKENPREF, user.getAuthenticationToken());
        editor.commit();
    }
    

    Ta metoda przechowuje identyfikator użytkownika i token w pliku preferencji, który jest oznaczony jako prywatny. Powinno to chronić dostęp do pamięci podręcznej, dzięki czemu inne aplikacje na urządzeniu nie będą mieć dostępu do tokenu. Preferencje aplikacji są piaskownicą. Jeśli jednak ktoś uzyska dostęp do urządzenia, może uzyskać dostęp do pamięci podręcznej tokenu za pośrednictwem innych środków.

    Uwaga

    Możesz dodatkowo chronić token za pomocą szyfrowania, jeśli dostęp do tokenu do danych jest uznawany za wysoce poufny i ktoś może uzyskać dostęp do urządzenia. Jednak całkowicie bezpieczne rozwiązanie wykracza poza zakres tego samouczka i zależy od wymagań dotyczących zabezpieczeń.

  4. W pliku ToDoActivity.java dodaj następującą definicję metody loadUserTokenCache .

    private boolean loadUserTokenCache(MobileServiceClient client)
    {
        SharedPreferences prefs = getSharedPreferences(SHAREDPREFFILE, Context.MODE_PRIVATE);
        String userId = prefs.getString(USERIDPREF, null);
        if (userId == null)
            return false;
        String token = prefs.getString(TOKENPREF, null);
        if (token == null)
            return false;
    
        MobileServiceUser user = new MobileServiceUser(userId);
        user.setAuthenticationToken(token);
        client.setCurrentUser(user);
    
        return true;
    }
    
  5. W pliku ToDoActivity.java zastąp authenticate metody i onActivityResult następującymi metodami, które wykorzystują pamięć podręczną tokenów. Zmień dostawcę logowania, jeśli chcesz używać konta innego niż Google.

    private void authenticate() {
        // We first try to load a token cache if one exists.
        if (loadUserTokenCache(mClient))
        {
            createTable();
        }
        // If we failed to load a token cache, sign in and create a token cache
        else
        {
            // Sign in using the Google provider.
            mClient.login(MobileServiceAuthenticationProvider.Google, "{url_scheme_of_your_app}", GOOGLE_LOGIN_REQUEST_CODE);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // When request completes
        if (resultCode == RESULT_OK) {
            // Check the request code matches the one we send in the sign-in request
            if (requestCode == GOOGLE_LOGIN_REQUEST_CODE) {
                MobileServiceActivityResult result = mClient.onActivityResult(data);
                if (result.isLoggedIn()) {
                    // sign-in succeeded
                    createAndShowDialog(String.format("You are now signed in - %1$2s", mClient.getCurrentUser().getUserId()), "Success");
                    cacheUserToken(mClient.getCurrentUser());
                    createTable();
                } else {
                    // sign-in failed, check the error message
                    String errorMessage = result.getErrorMessage();
                    createAndShowDialog(errorMessage, "Error");
                }
            }
        }
    }
    
  6. Skompilowanie aplikacji i przetestowanie uwierzytelniania przy użyciu prawidłowego konta. Uruchom go co najmniej dwa razy. Podczas pierwszego uruchomienia powinien zostać wyświetlony monit o zalogowanie się i utworzenie pamięci podręcznej tokenów. Następnie każdy przebieg próbuje załadować pamięć podręczną tokenu do uwierzytelniania. Zalogowanie się nie powinno być konieczne.

Następne kroki

Po ukończeniu tego samouczka uwierzytelniania podstawowego rozważ kontynuowanie pracy z jednym z następujących samouczków: