Documentation
¶
Overview ¶
Package ceremonyhttp — поверхность церемонии OAuth 2.1 `authorization_code` нашими силами (приёмка LINE-A-1, воркспейс, SHA-256 `b755886f…`; задача PRO-Robotech/kaname#423): эндпоинт авторизации, метаданные обнаружения и полосы `authorization_code` и `refresh_token` токен-эндпоинта.
Движок — фундамента, поверхность — наша ¶
Протокол исполняет церемония фундамента (`corelib/oauthceremony`): разбор запроса, PKCE, выдача и погашение кода, оборот токена обновления, отзыв семейства на повторе. Своего движка здесь нет. Порядок, в котором спрашиваются справочник клиентов, шов входа (приёмка Р2) и церемония, решения домена — уровень входа, граница семейства, отказ клиенту без получателя — и граница транзакции обмена принадлежат вариантам использования (`internal/apps/kaname/api/oauth_ceremony`). Этот пакет разбирает запрос, зовёт вариант использования и оформляет ответ: решает, КУДА можно отвечать (Р4), держит однозначность параметров, пол `state` (Р13) и единый тон отказов (Р10), ведёт счёт исходов и журнал.
Порядок решений на эндпоинте авторизации — несущий ¶
- метод; затем темп источника (П4) и потолок одновременных (П5) — до справочника клиентов и хранилища сессий, которые они берегут, и до доверия цели: оба отказа — прямо, без перенаправления (приёмка ceremony-pace-is-named-by-number.md, Р6);
- клиент и адрес возврата — ТОЧНЫМ равенством с регистрацией. До этого шага цели нет: отказ показывается БЕЗ перенаправления и побайтово одинаков для «клиента нет», «клиент снимается» и «адрес не тот» (Р4, сценарии 04/05);
- `state` не ниже пола — отказ ПЕРЕНАПРАВЛЯЕМ и несёт только `error` (Р13, 29/30);
- протокол (тип ответа, PKCE S256, область) — церемонией; отказ перенаправляем, только `error` (06/07);
- шов входа: нет сессии — вызов аутентификации (03); уровень ниже запрошенного `acr_values` — вызов шага вверх (08). Оба уходят ПРИЛОЖЕНИЮ перенаправлением на доверенную цель с `error` и `state` дословно (приёмка ceremony-pace-is-named-by-number.md, Р11);
- выдача кода; согласие первопартийного клиента не спрашивается (09).
Протокол судится раньше входа: человека не просят войти ради запроса, который кода не получит.
Index ¶
Constants ¶
const AuthorizePath = "/iam/v1/authorize"
AuthorizePath — путь эндпоинта авторизации (приёмка §5, группа A).
#nosec G101 -- это АДРЕС поверхности, а не учётные данные.
const DiscoveryPath = "/.well-known/oauth-authorization-server"
DiscoveryPath — путь метаданных обнаружения (RFC 8414 §3, приёмка группа H). Путь без суффикса издателя: издатель — начало координат (см. Endpoints).
const StateFloor = 22
StateFloor — пол длины `state` в знаках (приёмка Р13 п. 2): длина записи BASE64URL от 16 случайных байтов, самая короткая форма 128-битного значения. НАША величина, а не умолчание движка; движку она передаётся тем же значением (`oauthceremony.Config.MinParameterEntropy`).
Variables ¶
This section is empty.
Functions ¶
func DeclaredOutcomes ¶
func DeclaredOutcomes() []string
DeclaredOutcomes — словарь строками: читателю величин набор рядов витрины обязан совпадать с набором клеток переписи by construction.
func Endpoints ¶
Endpoints выводит адреса точек церемонии из издателя.
Издатель — начало координат сервера авторизации (RFC 8414 §2): метаданные публикуются под ним (DiscoveryPath), и точки, которые они называют, стоят на той же поверхности. Издатель с путём RFC 8414 допускает, но тогда адрес метаданных несёт путь издателя суффиксом (§3.1), а поверхность монтирует DiscoveryPath без суффикса — такой издатель отвергается, а не публикуется с адресом, по которому метаданных нет.
Types ¶
type Authorize ¶
type Authorize struct {
// contains filtered or unexported fields
}
Authorize — эндпоинт авторизации `GET /iam/v1/authorize`.
func NewAuthorize ¶
func NewAuthorize(cfg AuthorizeConfig) (*Authorize, error)
NewAuthorize строит эндпоинт. Неполная провязка — отказ построения.
type AuthorizeConfig ¶
type AuthorizeConfig struct {
// UseCase — выдача кода: доверие цели, решения домена и сроки вызовов
// хранилища (`internal/apps/kaname/api/oauth_ceremony`).
UseCase *ceremonyapp.AuthorizeUseCase
Census *Census
Logger *slog.Logger
// Pace — запросов авторизации в секунду на источник (П4), ведро в одну
// секунду темпа. Тратит его всякий запрос, прошедший проверку метода.
Pace *exchangepace.Pace
// InFlightCeiling — потолок одновременных запросов авторизации на процесс
// (П5). Свой, отдельный от потолка токен-эндпоинта: поток обменов не
// отнимает мест у навигаций людей, и наоборот.
InFlightCeiling int
// Source — адрес источника запроса по правилу Р7 (`issuingsource`).
Source func(*http.Request) string
}
AuthorizeConfig — зависимости эндпоинта авторизации. Все обязательны.
type Census ¶
type Census struct {
// contains filtered or unexported fields
}
Census — перепись исходов, засеянная ЦЕЛИКОМ по словарю при сборке.
type Discovery ¶
type Discovery struct {
// contains filtered or unexported fields
}
Discovery — метаданные обнаружения `GET /.well-known/oauth-authorization-server`: публичное неаутентифицированное чтение (паритет с набором ключей).
func NewDiscovery ¶
func NewDiscovery(cfg DiscoveryConfig) (*Discovery, error)
NewDiscovery собирает документ ОДИН раз: у него нет состояния, и каждый ответ побайтово один и тот же.
type DiscoveryConfig ¶
type DiscoveryConfig struct {
// Issuer — наш издатель, ДОСЛОВНО тот, что стоит в `iss` выпускаемых
// токенов (RFC 8414 §3.3).
Issuer string
// AuthorizationEndpoint, TokenEndpoint — адреса точек (см. Endpoints).
AuthorizationEndpoint string
TokenEndpoint string
// GrantTypes — виды выдачи токен-эндпоинта: церемонии и машинные полосы.
GrantTypes []string
// Scopes — области, которые интерактивный клиент вправе запросить.
Scopes []string
}
DiscoveryConfig — что публикуют метаданные. Все поля — публичный материал (приёмка Р11): координаты и словари, ни секретов, ни данных арендатора, ни инфраструктуры.
type Outcome ¶
type Outcome string
Outcome — исход обращения к поверхности церемонии. Словарь ЗАКРЫТ: у каждого значения свой счётчик, заведённый при сборке (Census), — «ноль отказов за всю жизнь полосы» обязан отличаться от «полоса не исполнялась ни разу».
Наружу отказы после именования кода неразличимы (приёмка Р10), а отказы до доверия цели — неразличимы между собой (Р4). Различимость для нас живёт здесь и в журнале.
const ( OutcomeAuthorizeMethodNotAllowed Outcome = "authorize-method-not-allowed" OutcomeAuthorizeRequestMalformed Outcome = "authorize-request-malformed" OutcomeAuthorizeClientUnknown Outcome = "authorize-client-unknown" OutcomeAuthorizeRedirectUnregistered Outcome = "authorize-redirect-unregistered" OutcomeAuthorizeStateBelowFloor Outcome = "authorize-state-below-floor" OutcomeAuthorizeProtocolRefused Outcome = "authorize-protocol-refused" OutcomeAuthorizeLoginRequired Outcome = "authorize-login-required" OutcomeAuthorizeStepUpRequired Outcome = "authorize-step-up-required" OutcomeAuthorizeIssued Outcome = "authorize-code-issued" // OutcomeAuthorizeSourcePaceExceeded — источник исчерпал темп точки // авторизации (П4, kaname#315). Решается до справочника клиентов. OutcomeAuthorizeSourcePaceExceeded Outcome = "authorize-source-pace-exceeded" // OutcomeAuthorizeInFlightCeilingReached — занят потолок одновременных // запросов авторизации (П5, kaname#315). Решается до справочника клиентов. OutcomeAuthorizeInFlightCeilingReached Outcome = "authorize-in-flight-ceiling-reached" )
Исходы эндпоинта авторизации.
const ( OutcomeExchangeRequestRefused Outcome = "token-request-refused" OutcomeExchangeClientRefused Outcome = "token-client-refused" OutcomeExchangeGrantRefused Outcome = "token-grant-refused" OutcomeExchangeCodeExchanged Outcome = "token-code-exchanged" OutcomeExchangeRefreshed Outcome = "token-refreshed" // OutcomeExchangeOwnerUnverified — правило выдачи ответило «владелец не // подтвердил адрес» (kaname#456, Р5б). Своя клетка рядом с отказом гранта: // отсечку и неподтверждённость снимают разные действия. OutcomeExchangeOwnerUnverified Outcome = "token-owner-unverified" )
Исходы полос обмена токен-эндпоинта.
type TokenLane ¶
type TokenLane struct {
// contains filtered or unexported fields
}
TokenLane — полосы `authorization_code` и `refresh_token` токен-эндпоинта.
Метод, потолок тела, разбор формы и перечень видов выдачи судит эндпоинт (`clienttokenhttp.Handler`) ДО полосы; полоса получает разобранную форму.
Единый тон после именования кода (приёмка Р10) ¶
Всякий отказ, наступивший после того, как назван код либо токен обновления, — неизвестен, истёк, уже использован, неверный `code_verifier`, клиент не тот, адрес возврата не тот — отдаёт побайтово `{"error":"invalid_grant"}`. Различимы только отказы, решённые ДО этого: форма запроса и аутентификация конфиденциального клиента (`invalid_client`, о клиенте, не о коде).
func NewTokenLane ¶
func NewTokenLane(exchange *ceremonyapp.ExchangeUseCase, census *Census, logger *slog.Logger) (*TokenLane, error)
NewTokenLane строит полосы. Неполная провязка — отказ построения.
func (*TokenLane) Grants ¶
Grants — виды выдачи полосы: словарь церемонии фундамента, а не выписанные слова. Набор собран при построении; наружу — копия.
func (*TokenLane) ServeGrant ¶
func (l *TokenLane) ServeGrant(w http.ResponseWriter, r *http.Request, grant string) clienttokenhttp.LaneVerdict
ServeGrant обслуживает вид выдачи grant по разобранной форме запроса.
Возвращает эндпоинту, отвергнуто ли доказательство клиента (`invalid_client`): этот отказ засчитывает ось П3 эндпоинта, прочие — нет (приёмка ceremony-pace-is-named-by-number.md, Р5).