Реагировать на проблему SPA/Embedded Identity Server после обновления .net core 3 preview 8

У нас есть React SPA, который был изначально создан с использованием шаблонов SPA и запущен на предварительном просмотре .NET Core 3 7. React SPA "Клиент" был настроен для неявного потока и успешно использовал oidc-client. Все работает.

Вот конфиг клиента в моем файле startup.cs:

        var mySPAClient = new IdentityServer4.Models.Client()
        {
            AccessTokenLifetime = accessTokenLifetime,
            RedirectUris =
                {
                    $"{host}/authentication/login-callback",
                    $"{host}/silent-refresh.html"
                },
            PostLogoutRedirectUris =
                {
                    $"{host}/authentication/logout-callback"
                },
            ClientId = "projectName.web",
            AllowedScopes =
                {
                    "projectName.webAPI",
                    "openid",
                    "profile"
                },
            ClientName = "projectName.web",
            RequireConsent = false,
            AllowedGrantTypes =
                {
                    IdentityModel.OidcConstants.GrantTypes.Implicit
                },
            AllowAccessTokensViaBrowser = true,
        };

Но теперь, когда я обновляюсь до предварительного просмотра 8 для любой сборки, которая была предварительным просмотром 7, я получаю следующую ошибку в журналах

[10:55:34 Error] Invalid grant type for client: "authorization_code" AuthorizeRequestValidationLog { ClientId: "projectName.web", ClientName: "projectName.web", RedirectUri: "https://localhost:44343/authentication/login-callback", AllowedRedirectUris: ["https://localhost:44343/authentication/login-callback", "https://localhost:44343/silent-refresh.html"], SubjectId: "anonymous", ResponseType: "code", ResponseMode: "query", GrantType: "authorization_code", RequestedScopes: "", State: "a1e84334a8c94b7db599ddb9336447c8", UiLocales: null, Nonce: null, AuthenticationContextReferenceClasses: null, DisplayMode: null, PromptMode: null, MaxAge: null, LoginHint: null, SessionId: null, Raw: [("client_id": "projectName.web"), ("redirect_uri": "https://localhost:44343/authentication/login-callback"), ("response_type": "code"), ("scope": "projectName.webAPI openid profile"), ("state": "a1e84334a8c94b7db599ddb9336447c8"), ("code_challenge": "E8p1sg1Y0TdbhxccGB-_fbx7D6GnJXfCpcYu1IHZC_k"), ("code_challenge_method": "S256"), ("prompt": "none")] } (IdentityServer4.Validation.AuthorizeRequestValidator) [10:55:34 Error] Request validation failed (IdentityServer4.Endpoints.AuthorizeEndpoint)

Я не знаю, почему он ссылается на код авторизации, и эта ошибка появляется?

Приветствия за любую помощь

Ответы

Ответ 1

Измените response_type на "token", а не "code", и с вами все будет в порядке

Обновление:

Убедитесь, что вы предоставили правильные настройки authority, client_id, response_type, scope

Ответ 2

Я понял свой. Но не уверен, применимо ли это к твоему. Проблема в моем случае заключается в том, что у меня есть процесс, который как-то не соответствует. Когда я попытался изменить образец React with Auth для использования EF Core, вызов updateState не был выполнен в AuthorizeService.js/completeSignIn(). Кажется, что код вызывает другой вызов конечной точки токена, прежде чем он возвращается к SignIn(), без вызова updateState() для сохранения состояния. И это терпит неудачу второй, так как код истек после первого вызова. Я как-то нашел другой исходный код из примера React с Redux, который имеет необходимый вызов updateState() в completeSignIn(). Кроме отличного файла AuthorizeService.js, другой код, связанный с аутентификацией/авторизацией, одинаков между образцом React with Auth и образцом React with Redux. Это новый код completeSignIn:

    async completeSignIn(url) {
        await this.ensureUserManagerInitialized();
        try {
            const { state } = await this.userManager.readSigninResponseState(url, this.userManager.settings.stateStore);
            if (state.request_type === 'si:r' || !state.request_type) {
                let user = await this.userManager.signinRedirectCallback(url);
                this.updateState(user);
                return this.success(state.data.userState);
            }
            if (state.request_type === 'si:p') {
                await this.userManager.signinSilentCallback(url);
                return this.success(undefined);
            }
            if (state.request_type === 'si:s') {
              await this.userManager.signinSilentCallback(url);
              return this.success(undefined);
            }

            throw new Error('Invalid login mode '${state.request_type}'.');
        } catch (signInResponseError) {
            console.log('There was an error signing in', signInResponseError);
            return this.error('Sing in callback authentication error.');
        }
    }