Современные стандарты идентификации: oauth 2.0, openid connect, webauthn

Содержание

ID Token Validation

Verifying an ID Token signed with the RS256 signing algorithm

To verify an ID Token that is signed using the RS256 signing algorithm, you will need to provide an implementation of that will return the public key used to verify the token’s signature. The example below demonstrates how to use the from the jwks-rsa-java library:

JwkProvider provider = new JwkProviderBuilder("https://your-domain.auth0.com").build();
SignatureVerifier sigVerifier = SignatureVerifier.forRS256(new PublicKeyProvider() {
    @Override
    public RSAPublicKey getPublicKeyById(String keyId) throws PublicKeyProviderException {
       try {
            return (RSAPublicKey) provider.get(keyId).getPublicKey();
        } catch (JwkException jwke) {
            throw new PublicKeyProviderException("Error obtaining public key", jwke);
        }
    }
}

IdTokenVerifier idTokenVerifier = IdTokenVerifier.init("https://your-domain.auth0.com/","your-client-id", signatureVerifier).build();

try {
    idTokenVerifier.verify("token", "expected-nonce");
} catch(IdTokenValidationException idtve) {
    // Handle invalid token exception
}

Verifying an ID Token signed with the HS256 signing algorithm

To verify an ID Token that is signed using the HS256 signing algorithm:


SignatureVerifier signatureVerifier = SignatureVerifier.forHS256("your-client-secret");
IdTokenVerifier idTokenVerifier = IdTokenVerifier.init("https://your-domain.auth0.com/","your-client-id", signatureVerifier).build();

try {
    idTokenVerifier.verify("token", "expected-nonce");
} catch(IdTokenValidationException idtve) {
    // Handle invalid token exception
}

Additional configuration options

By default, time-based claims such as the token expiration ( claim) will allow for a leeway of 60 seconds. You can customize the leeway by using the when building the :

IdTokenVerifier idTokenVerifier = IdTokenVerifier.init("https://your-domain.auth0.com/","your-client-id", signatureVerifier)
        .withLeeway(120) // two minutes
        .build();

When verifying the token, the following methods are available to support different scenarios:

// Verify the token's signature and claims, excluding the nonce and auth_time claims
idTokenVerifier.verify("token");

// Verify the token's signature and claims, including the nonce.
// The expected nonce should be the nonce sent on the authorization request.
idTokenVerifier.verify("token", "expected-nonce");

// Verify the token's signature and claims, including the nonce and the auth_time claim.
// The maxAuthenticationAge parameter specifies the maximum amount of time since the end-user last actively authenticated,
// and it should match the max_age parameter sent on the authorization request.
idTokenVerifier.verify("token", "expected-nonce", 24 * 60 * 60); // maximum authentication age of 24 hours

Creating an Application

The registration process typically involves creating an account on the service’s website, then entering basic information about the application such as the name, website, logo, etc. After registering the application, you’ll be given a (and a in some cases) that you’ll use when your app interacts with the service.

One of the most important things when creating the application is to register one or more redirect URLs the application will use. The redirect URLs are where the OAuth 2.0 service will return the user to after they have authorized the application. It is critical that these are registered, otherwise it is easy to create malicious applications that can steal user data. This is covered in more detail later in this book.

Install

From CDN

<!-- Latest patch release (recommended for production) -->
<script src="https://cdn.auth0.com/js/lock/11.26.3/lock.min.js"></script>
npm install auth0-lock

Then you can import or like this:

import Auth0Lock from 'auth0-lock';
// OR
import { Auth0Lock } from 'auth0-lock';
import { Auth0LockPasswordless } from 'auth0-lock';

After installing the module, you’ll need to bundle it up along with all of its dependencies. See examples for browserify and webpack.

If you are targeting mobile audiences, we recommended that you add:

<meta name="viewport" content="width=device-width, initial-scale=1"/>

Шаг 4. Получение информации о пользователе

Теперь, когда у нас есть параметры access_token, мы можем сделать запрос к Yandex API и получить информацию о пользователе:

if (isset($tokenInfo)) {
    $params = array(
        'format'       => 'json',
        'oauth_token'  => $tokenInfo
    );
}

В параметр format передаём значение json — формат возвращаемых данных; в oauth_token записываем access_token — токен доступа, который мы достали по POST запросу в предыдущем шаге.

Для получения информации о пользователе сформированные параметры нам нужно отправить GET запросом по адресу https://login.yandex.ru/info:

$userInfo = json_decode(file_get_contents('https://login.yandex.ru/info' . '?' . urldecode(http_build_query($params))), true);

В результате, если всё было сделано успешно, то получим JSON ответ. Преобразуем его сразу же в массив:

Array
(
     => stanislav.protasevich
     => Протасевич Станислав
     => male
     => 1988-07-03
     => 203179654
     => stanislav.protasevich@yandex.com
     => Array
        (
             => stanislav.protasevich@yandex.com
        )
)

Если в массиве есть ключ id, то записываем пришедший массив в переменную $userInfo:

if (isset($userInfo)) {
    $userInfo = $userInfo;
    $result = true;
}

Полный код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <title>Аутентификация через Yandex</title>
</head>
<body>

<?php

$client_id = '22d7dfc5f4358b47b41f6e1f8a80efa0'; // Id приложения
$client_secret = '721a338df24447efe9080cfd36a2da7a'; // Пароль приложения
$redirect_uri = 'http://localhost/yandex-auth'; // Callback URI

$url = 'https://oauth.yandex.ru/authorize';

$params = array(
    'response_type' => 'code',
    'client_id'     => $client_id,
    'display'       => 'popup'
);

echo $link = '<p><a href="' . $url . '?' . urldecode(http_build_query($params)) . '">Аутентификация через Yandex</a></p>';

if (isset($_GET)) {
    $result = false;

    $params = array(
        'grant_type'    => 'authorization_code',
        'code'          => $_GET,
        'client_id'     => $client_id,
        'client_secret' => $client_secret
    );

    $url = 'https://oauth.yandex.ru/token';

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, urldecode(http_build_query($params)));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $result = curl_exec($curl);
    curl_close($curl);

    $tokenInfo = json_decode($result, true);

    if (isset($tokenInfo)) {
        $params = array(
            'format'       => 'json',
            'oauth_token'  => $tokenInfo
        );

        $userInfo = json_decode(file_get_contents('https://login.yandex.ru/info' . '?' . urldecode(http_build_query($params))), true);
        if (isset($userInfo)) {
            $userInfo = $userInfo;
            $result = true;
        }
    }
}

?>

</body>
</html>

Related

  • Tutorial

    Автор выбрал фонд Electronic Frontier Foundation для получения пожертвований в рамках программы Write for DOnations. Cloudflare — это…

  • Tutorial

    Автор выбрал фонд Electronic Frontier Foundation для получения пожертвований в рамках программы Write for DOnations. Cloudflare — это…

  • Tutorial

    TLS или протокол безопасности транспортного уровня и предшествующий ему протокол SSL используются для заключения обычного трафика в защищенную оболочку с шифрованием. Используя эту технологию, серверы могут безопасно отправлять информацию клиентам без перехвата сообщений и…

  • Tutorial
    Создание бота Slackbot на Python в Ubuntu 20.04

    Автор выбрал Tech Education Fund для получения пожертвования в рамках программы Write for DOnations. Slack — это коммуникационная платформа, предназначенная для продуктивной…

Books about OAuth 2.0


OAuth 2.0 Simplified by Aaron Parecki is a guide to building an OAuth 2.0 server. Through high-level overviews, step-by-step instructions, and real-world examples, you will learn how to take advantage of the OAuth 2.0 framework while building a secure API.

Whether you’re a software architect, application developer, project manager, or a casual programmer, this book will introduce you to the concepts of OAuth 2.0 and demonstrate what is required when building a server.

This book is currently available from Lulu.com and Amazon, and on Kindle.

The Little Book of OAuth 2.0 RFCs by Aaron Parecki is a collection of the core RFCs you’ll need to read in order to fully implement an OAuth 2.0 client or service. This book is a reproduction of all the RFCs relating to OAuth, everything from OAuth core RFC6749 to the latest Security Best Current Practice. Each RFC is prefaced by a short introduction to set the context for why it’s important to the space.

OAuth 2 in Action by Justin Richer and Antonio Sanso covers the OAuth 2 protocol in depth, providing hands-on exercises for building clients, authorization servers, and protected resources in various configurations. The book covers the structure and components of an OAuth 2 system, common vunlerabilities and mitigations, and several protocols that are built on and around OAuth 2. Exercises are included that walk through building an entire OAuth 2.0 ecosystem.

This book is currently available from Manning, Amazon, and wherever technical books are sold.

Mastering OAuth 2.0 by Charles Bihis provides an in-depth view of the OAuth 2.0 protocol from a client perspective. With a focus on practicality and security, this book explores the various ways in which a client can integrate with an OAuth 2.0 service provider, discussing caveats and best practices along the way.

This book focuses on the client integration side of the OAuth 2.0 protocol and is ideal for client and application developers looking to integrate with OAuth 2.0 service providers in the most secure and effective way.

This book is available from Packt and Amazon.


API Security in Action by Neil Madden covers use of OAuth 2 to protect REST APIs, and related technologies such as JSON Web Tokens. Security enhancements including combining OAuth 2 with mutual TLS authentication are covered, along with the latest security best practices. Detailed patterns are presented for using OAuth 2 with Kubernetes and for resource-constrained IoT (Internet of Things) environments.

This book is available in early-access from Manning with final publication expected in Summer 2020.

OAuth 2.0 Cookbook by Adolfo Eloy Nascimento provides useful recipes for solving real-life problems using Spring Security and creating Android applications.

The book starts by presenting you how to interact with some public OAuth 2.0 protected APIs such as Facebook, LinkedIn and Google. Readers will also be able to implement their own OAuth 2.0 provider with Spring Security OAuth2. Next, the book covers practical scenarios regarding some important OAuth 2.0 profiles such as Dynamic Client Registration, Token Introspection and how to revoke issued access tokens. Readers will then be introduced to the usage of JWT, OpenID Connect, and how to safely implement native mobile OAuth 2.0 Clients.

This book is available from Packt and Amazon.

Примечания

  1. D. Hardt, Ed.  (англ.). Internet Engineering Task Force (October 2012). Дата обращения 30 октября 2015.
  2. Eran Hammer.  (англ.). Дата обращения 30 октября 2015.
  3. E. Hammer-Lahav, Ed.  (англ.). Internet Engineering Task Force. Дата обращения 8 ноября 2015.
  4. Eran Hammer.  (англ.) (недоступная ссылка). hueniverse.com. Дата обращения 30 октября 2015.
  5.  (англ.). oauth.net. Дата обращения 30 октября 2015.
  6.  (англ.). .
  7.  (англ.). developers.google.com.
  8. Eran Hammer.  (англ.). hueniverse (26 July 2012). Дата обращения 14 июня 2017.
  9. Eran Hammer.  (англ.). hueniverse. Дата обращения 30 октября 2015.
  10. D. Hardt.  (англ.) (1 August 2012). Дата обращения 30 октября 2015.
  11. Eran Hammer.  (англ.). hueniverse. Дата обращения 31 октября 2015.
  12. Eran Hammer.  (англ.). hueniverse. Дата обращения 31 октября 2015.

Environment variables and multiple Auth0 apps

If you are using for just one shiny app or you are running many apps for the same user database, the recommended workflow is using the environment variables and .

However, if you are running many shiny apps and want to use different login settings, you must create many Auth0 apps. Hence, you’ll have many Cliend IDs and Client Secrets to use. n this case, global environment variables will be unproductive because you’ll need to change them every time you change the app you are developing.

There are two options in this case:

  • (Recommended) Add environment variables inside the repository of your application, using .
  • (Not recommended) Add the Client ID and Secret directly in the _auth0.yml file:

The best option in this case is to simply add the Client ID and Secret directly in the file:

name: myApp
remote_url: ''
auth0_config:
  api_url: https://<USERNAME>.auth0.com
  credentials:
    key: <CLIENT_ID>
    secret: <CLIENT_SECRET>

Example:

name: myApp
remote_url: ''
auth0_config:
  api_url: https://johndoe.auth0.com
  credentials:
    key: cetQp0e7bdTNGrkrHpuF8gObMVl8vu
    secret: C6GHFa22mfliojqPyKP_5K0ml4TituWrOhYvLdTa7veIyEU3Q10R_-If-7Sh6Tc

Although possible, the latter option is less secure and consequently not recommended because it’s easy to forget passwords there and commit them in public repositories, for example.

Применение

Одной из проблем аутентификации и информационной безопасности является тот факт, что у одного пользователя, как правило, имеется несколько учётных записей на различных сервисах (например, на Google, Twitter, Apple и др.). При этом человеку приходится для каждого из сервисов иметь отдельные логин и пароль. В то же время, каждый из сервисов имеет свою систему безопасности, каждая из которых имеет свои уязвимости и недостатки. Как следствие, пользователям нужно хранить и защищать множество логинов-паролей, что вредит как удобству, так и безопасности; когда, например, пользователи для разных сервисов начинают использовать одни и те же пароли. В то же время, в данных обстоятельствах злоумышленникам становится проще осуществлять взлом (например, после получения доступа к одной из учётных записей взлом других может быть облегчён).

Для улучшения защиты может быть использована аутентификация в два шага (например Google Authenticator), когда для подтверждения задействуется другой сервис пользователя (например, когда для аутентификации на веб-сайте требуется ввести кодовое слово, отправляемое на мобильный телефон). В этом случае вероятность взлома значительно уменьшается. Ключевая особенность применения OAuth заключается в том, что, если пользователь имеет подобный хорошо защищённый аккаунт, то с его помощью и технологии OAuth он может пройти аутентификацию на других сервисах, и при этом ему не требуется раскрывать свой основной пароль. Например, пользователь, который хочет предоставить онлайн-сервису печати фотографий доступ к фотографиям своего , не должен сообщать сервису пароль от этого аккаунта. Вместо этого он проходит авторизацию непосредственно в Facebook’е, который (с разрешения пользователя или администратора сервиса) предоставляет сервису онлайн-печати полномочия доступа к фотографиям.

Тип разрешения на авторизацию: Код авторизации

Код авторизации является одним из наиболее распространённых типов разрешения на авторизацию, поскольку он хорошо подходит для серверных приложений, где исходный код приложения и секрет клиента не доступны посторонним. Процесс в данном случае строится на перенаправлении (redirection), что означает, что приложение должно быть в состоянии взаимодействовать с пользовательским агентом (user-agent), например, веб-браузером, и получать коды авторизации API, перенаправляемые через пользовательский агент.

Опишем процесс на диаграмме:

Шаг 1: Ссылка с кодом авторизации

Сначала пользователю предоставляется ссылка следующего вида:

Рассмотрим компоненты ссылки:

  • https://cloud.digitalocean.com/v1/oauth/authorize: входная точка API авторизации (API authorization endpoint).
  • client_id=CLIENT_ID: идентификатор клиента приложения (с помощью этого идентификатора API понимает, какое приложение запрашивает доступ).
  • redirect_uri=CALLBACK_URL: URL, на который сервис перенаправит пользовательского агент (браузер) после выдачи авторизационного кода.
  • response_type=code: указывает на то, что приложение запрашивает доступ с помощью кода авторизации.
  • scope=read: задаёт уровень доступа приложения (в данном случае — доступ на чтение).

Шаг 2: Пользователь авторизует приложение


Когда пользователь нажимает на ссылку, он должен сперва осуществить вход в систему для подтверждения своей личности (если он, конечно, ещё не залогинен). После этого сервис предложит пользователю авторизовать или отказать в авторизации приложению для доступа к аккаунту пользователя. Пример такого диалога представлен ниже:

На этом скриншоте экрана авторизации DigitalOcean мы можем видеть, что приложение “Thedropletbook App” запрашивает доступ на чтение к аккаунту “manicas@digitalocean.com”.

Шаг 3: Приложение получает код авторизации

Если пользователь выбирает “Авторизовать приложение”, сервис перенаправляет пользовательский агент (браузер) по URL перенаправления (redirect URL), который был задан на этапе регистрации клиента (вместе с кодом авторизации). Ссылка будет выглядеть похожим образом (в данном примере приложение называется “dropletbook.com”):

Шаг 4: Приложение запрашивает токен доступа

Приложение запрашивает токен доступа у API путём отправки авторизационного кода и аутентификационной информации (включая секрет клиента) сервису. Ниже представлен пример POST-запроса для получения токена DigitalOcean:

Шаг 5: Приложение получает токен доступа

Если авторизация прошла успешно, API возвращает токен доступа (а также, опционально, токен для обновления токена доступа — refresh token). Весь ответ сервера может выглядеть следующим образом:

Теперь приложение авторизовано! Оно может использовать токен для доступа к пользовательскому аккаунту через API сервиса с заданными ограничениями доступа до тех пор, пока не истечёт срок действия токена или токен не будет отозван. Если был создан токен для обновления токена доступа, он может быть использован для получения новых токенов доступа, когда истечёт срок действия старого токена.

Регистрация приложения

Перед тем, как начать использовать OAuth в вашем приложении, вам необходимо зарегистрировать своё приложения в сервисе. Это делается путём регистрации в разделе “developer” или “API” сайта сервиса, где вам необходимо предоставить следующую информацию (возможно, включая некоторые детали о вашем приложении):

  • Название приложения
  • Сайт приложения
  • Redirect URL или callback URL

Redirect URL — это URL, на который сервис будет перенаправлять пользователя после авторизации (или отказа в авторизации) вашего приложения.

Идентификатор клиента и секрет клиента

После регистрации приложения сервис создаст учётные данные клиента — идентификатор клиента (client ID) и секрет клиента (client secret). Идентификатор клиента представляет собой публично доступную строку, которая используется API сервиса для идентификации приложения, а также используется для создания авторизационных URL для пользователей. Секрет клиента используется для аутентификации подлинности приложения для API сервиса, когда приложение запрашивает доступ к аккаунту пользователя. Секрет клиента должен быть известен только приложению и API.

OAuth 2.0

OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. This specification and its extensions are being developed within the IETF OAuth Working Group.

OAuth 2.0

  • OAuth 2.0 Framework

    OAuth Scope

    — RFC 6749
  • OAuth Grant Types
    • Authorization Code
    • PKCE
    • Client Credentials
    • Device Code
    • Refresh Token
    • Legacy: Implicit Flow
    • Legacy: Password Grant
  • Client Types — Confidential and Public Applications
  • Bearer Tokens — RFC 6750
  • Threat Model and Security Considerations — RFC 6819
  • OAuth Security Best Current Practice

Mobile and Other Devices

  • Native Apps — Recommendations for using OAuth with native apps
  • Browser-Based Apps — Recommendations for using OAuth with browser-based apps (e.g. an SPA)
  • Device Authorization Grant — OAuth for devices with no browser or no keyboard

Token and Token Management

  • Token Introspection — RFC 7662, to determine the active state and meta-information of a token
  • Token Revocation — RFC 7009, to signal that a previously obtained token is no longer needed
  • JSON Web Token — RFC 7519

Discovery and Registration

  • Authorization Server Metadata — RFC 8414, for clients to discover OAuth endpoints and authorization server capabilities
  • Dynamic Client Registration — RFC 7591, to programmatically register OAuth clients
  • Dynamic Client Registration Management — Experimental RFC 7592, for updating and managing dynamically registered OAuth clients

Experimental and Draft Specs

The specs below are either experimental or in draft status and are still active working group items. They will likely change before they are finalized as RFCs or BCPs.

  • JWT Profile for Access Tokens
  • Rich Authorization Requests (RAR)
  • Pushed Authorization Requests (PAR)
  • Demonstration of Proof of Possession (DPoP)
  • Incremental Authorization
  • OAuth WG Status Pages

Related Specs and Extensions

  • OAuth Assertions Framework — RFC 7521
  • SAML2 Bearer Assertion — RFC 7522, for integrating with existing identity systems
  • JWT Bearer Assertion — RFC 7523, for integrating with existing identity systems
  • WebAuthn — Web Authentication

Community Resources

  • OAuth 2.0 Simplified
  • Books about OAuth
    • OAuth 2.0 Simplified by Aaron Parecki
    • OAuth 2 in Action by Justin Richer and Antonio Sanso
    • Mastering OAuth 2.0 by Charles Bihis
    • OAuth 2.0 Cookbook by Adolfo Eloy Nascimento
  • OAuth articles by Alex Bilbie

OAuth 1.0 and 1.0a

Enterprise

These specs support more advanced enterprise use cases.

Assertion Framework (RFC 7521)

This spec provides a framework for using assertions with OAuth 2.0. It defines a new client authentication mechanism and a new authorization grant type. As this spec is also a framework, it is only useful with one of the specific assertion types described below.

JWT Assertions (RFC 7523)

This spec describes how a JWT can be used to request an access token when there is an existing trust relationship with the client as described by the contents of the JWT. It also describes how a JWT can be used as client authentication for the core OAuth grants.

SAML Assertions (RFC 7522)

This spec describes how a SAML Assertion can be used to request an access token when there is an existing trust relationship with the client. This can be used, for example, to integrate legacy SAML workflows with new OAuth 2.0 systems.


С этим читают