簡體   English   中英

Azure AD B2C 注銷問題

[英]Azure AD B2C Sign-out issue

我在 Azure B2C 中的注銷存在問題。

我在 1 年前配置了登錄,並且運行良好(而且這里提供的文檔非常簡單

對於注銷,我遵循此處提供的文檔,但即使它看起來正在運行(我被重定向到配置的 URL),如果我再次單擊鏈接以通過 Azure SSO 登錄,它也不會要求我的登錄名和密碼並直接連接我。 我想這是配置的問題,但由於沒有太多關於注銷的東西可以更改,我真的不明白問題出在哪里。

這是我的代碼(我的項目在后端的 java 中):

1-建立登錄網址:

public String buildAuthorisationUrl(final String nonce, final Item item)
{
    final ExternalSystemConfigData azureConfig = retrieveAzureConfig(item);

    final String tenantId = azureConfig.getPropertyValue(Azure.TENANT_ID_KEY);
    final String policy = azureConfig.getPropertyValue(Azure.POLICY_KEY);
    final String clientId = azureConfig.getPropertyValue(Azure.CLIENT_ID_KEY);
    final String redirectUrl = azureConfig.getPropertyValue(Azure.REDIRECT_URL_KEY);

    try
    {
        return "https://" + tenantId + ".b2clogin.com/" + tenantId + ".onmicrosoft.com/" + policy + "/oauth2/v2.0/authorize?" //
                + "client_id=" + clientId //
                + "&redirect_uri=" + URLEncoder.encode(redirectUrl, "UTF-8") //
                + "&response_mode=form_post" //
                + "&response_type=code" //
                + "&scope=" + clientId //
                + "&nonce=" + nonce;
    }
    catch (final UnsupportedEncodingException e)
    {
        LogUtil.error(getClass(), e, "Error when encoding redirect URL. Redirect-url=" + redirectUrl);
    }

    return null;
}

2- 從 Azure 登錄重定向 URL 重定向端點:

@ResponseBody
@RequestMapping(value = "/login-redirect", method = RequestMethod.POST)
public ModelAndView azureLoginRedirection(final HttpServletRequest request)
{
    try
    {
        // we need to rebuild the URL to get an Azure Authentication Response
        final Map<String, List<String>> params = request.getParameterMap().entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -> Collections.singletonList(e.getValue()[0])));
        final AuthenticationResponse authResponse = AuthenticationResponseParser.parse(new URI(request.getRequestURL().toString()), params);

        if (authResponse instanceof AuthenticationSuccessResponse) // successful authentication
        {
            final AuthenticationSuccessResponse oidcResponse = (AuthenticationSuccessResponse) authResponse;

            // validate that OIDC Auth Response matches Code Flow (contains only requested artifacts)
            validateAuthRespMatchesAuthCodeFlow(oidcResponse);

            final IAuthenticationResult result = azureConnectionService.retrieveAuthResultByAuthCode(request, oidcResponse.getAuthorizationCode(),
                    requestContextService.getContextSchool());

            // validate nonce to prevent reply attacks (code maybe substituted to one with broader access)
            final String nonce = getNonceClaimValueFromIdToken(result.idToken());
            final SessionInfos sessionInfos = requestContextService.getSessionInfos();
            final String bid = sessionInfos.getBid();
            if (DkObjectUtils.nullSafeEquals(bid, nonce))
            {
                LogUtil.info(getClass(), "ID Token : " + result.idToken());
                sessionInfos.setIdToken(result.idToken());
                final String email = getEmailFromIdToken(result.idToken());
                LogUtil.info(getClass(), String.format("User %s has been authenticated successfully by AZURE.", email));
                // Redirect to home page for user
                return controllerService.getRedirectViewExternal(urlService.getClientLoginUrl(sessionInfos.getUniqueConnectionId()));
            }
            else
            {
                LogUtil.error(getClass(), "The parameter 'nonce' can't be validated. BID=[{}] nonce=[{}]", bid, nonce);
            }
        }
        else
        {
            final AuthenticationErrorResponse oidcResponse = (AuthenticationErrorResponse) authResponse;
            LogUtil.error(getClass(), String.format("Request for auth code failed: %s - %s", oidcResponse.getErrorObject().getCode(),
                    oidcResponse.getErrorObject().getDescription()));
        }
    }
    catch (final Throwable e)
    {
        LogUtil.error(getClass(), e, e.getMessage());
    }

    // default redirection to login page with an error
    return controllerService.getRedirectViewExternal(urlService.getClientLoginUrl(ClientRedirectionErrorCodeEnum.LOGIN_EXTERNAL_CONNECTION_FAILURE));
}

3-建立注銷URL:

public String buildLogoutUrl(final Item item, final String idToken)
{
    final ExternalSystemConfigData azureConfig = retrieveAzureConfig(item);

    final String tenantId = azureConfig.getPropertyValue(Azure.TENANT_ID_KEY);
    final String policy = azureConfig.getPropertyValue(Azure.POLICY_KEY);
    final String redirectUrl = azureConfig.getPropertyValue(Azure.REDIRECT_LOGOUT_URL_KEY);

    try
    {
        return "https://" + tenantId + ".b2clogin.com/" + tenantId + ".onmicrosoft.com/" + policy + "/oauth2/v2.0/logout?" //
                + "&id_token_hint=" + idToken //
                + "&post_logout_redirect_uri=" + URLEncoder.encode(redirectUrl, "UTF-8");
    }
    catch (final UnsupportedEncodingException e)
    {
        LogUtil.error(getClass(), e, "Error when encoding redirect URL. Redirect-url=" + urlService.getClientUrl());
    }

    return null;
}

4- 從 Azure 注銷重定向 URL 重定向端點:

@ResponseBody
@RequestMapping(value = "/logout-redirect", method = RequestMethod.GET)
public ModelAndView azureLogoutRedirection()
{
    connectionService.disconnect();

    return controllerService.getRedirectViewExternal(urlService.getClientUrl());
}

最后在這里您可以看到我的 Azure 身份驗證配置: 在此處輸入圖像描述

  • 在 1 中,您有我的 2 個重定向 URL(如果我沒有將退出 URL 放在這里,我收到一條錯誤消息,指出“請求中提供的重定向 URL 未注冊客戶端 ID”)。
  • 在 2 中,我輸入了退出 URL,但不確定最終是否使用它,因為我必須將它也放入 1 中。

你看到我做錯了什么嗎?

請檢查您是否可以在啟動類的配置服務中重定向到帶有 http 上下文的注銷重定向。

options.Events.OnSignedOutCallbackRedirect = async context =>
{
    context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
    context.HandleResponse();
};

請檢查您是否可以添加控制器以這種方式注銷> azure-b2c-logout-implementation-in-asp-net-core

參考:

AzureADB2C.UI 不允許自定義注銷后重定向 URI · · GitHub

所以實際上我從微軟 Azure 論壇得到了答案,我也在那里提出了我的問題。

因此,如果有人正在尋找答案,問題只是我忘記在 buildAuthorisationUrl 方法中添加它:

+ "&prompt=login";

在請求的最后。 然后它完美地工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM