로그인 사용자의 WordPress <> Discourse SSO 문제

약 20만 명의 사용자가 있는 Discourse 포럼이 연결된 WordPress 웹사이트를 구축하고 있습니다.
OAuth Single Sign On - SSO (OAuth client) 및 WP-Discourse 플러그인을 사용하여 WordPress의 게시물을 Discourse에 연결하고, 사용자가 WordPress에서 자신의 WP 사용자 계정으로 로그인하면 Discourse에도 자동으로 로그인되도록 설정했습니다.

그러나 Discourse 설정에서 로그인 필수를 해제하면 문제가 발생합니다.

우리의 단계는 다음과 같습니다:

  1. 사용자가 WordPress에 로그인합니다.
  2. 사용자가 Discourse로 이어지는 링크(주제, Discourse로 가는 모든 링크)를 클릭합니다.
    ==> 사용자는 로그인하지 않은 상태인 것처럼 Discourse를 봅니다! 하지만 WordPress에 로그인하는 순간 이미 로그인되어 있어야 합니다!
  3. 이제 사용자가 Discourse 로그인 버튼을 클릭하거나 임의의 주제 링크를 클릭합니다.
  4. 페이지가 새로고달려지고 이제 사용자는 인증된 상태가 됩니다!

우리는 이것이 예상된 동작이며, 다음을 수행해야 한다고 들었습니다:

  • 사용자가 로그인된 상태라면, WordPress에서 Discourse로 이어지는 모든 링크는 반드시 다음과 같은 형태여야 합니다: https://our-discourse-instance.com/session/sso?return_path={DISCOURSE로 가려는 원래 URL, 예: 주제 URL 등}
  • 사용자가 로그아웃된 상태라면, https://our-discourse-instance.com/t/topic-slug와 같이 {DISCOURSE로 가려는 원래 URL, 예: 주제 URL 등}으로 직접 링크할 수 있습니다.

이것이 문제를 해결하는 잘못된 접근법이라고 강력히 의심하는 이유는 다음과 같습니다:

  1. 사용자가 Discourse에 로그인된 상태에서 주제 URL을 복사하여, WP/Discourse에 로그인된 다른 사람에게 공유한다고 가정해 봅시다. 해당 URL 뒤에 그런 접미사가 붙지 않으므로, 위에서 #2에 표시된 것과 동일한 오류가 발생합니다.
  2. 왜 _로그인된 사용자_가 session/sso?return_path=로 리다이렉트되어야 합니까? 이 기술적 근거와 논리는 무엇입니까?
  3. 왜 사용자가 페이지를 새로고달리면(주제 URL 로드, 로그인 클릭 등) 즉시 해결됩니까?
  4. 이것이 실제로 예상된 접근법이라면, 왜 이것이 더 널리 문서화되지 않았습니까?
  5. Discourse에서 모든 주제 URL을 가져올 수 있는 API에서 왜 이것이 언급되지 않습니까? 로그인된 사용자가 즉시 콘텐츠에 접근할 수 없고 먼저 이상한 새로고침을 해야 하거나, 실제로는 아무것도 변환하지 않는 이상한 URL 매개변수를 붙여야 한다는 내용이 어디에도 적혀 있지 않습니다.

이것이 예상된 동작이라고 전혀 확신이 서지 않으므로, 이에 대한 권위 있는 의견을 정말로 듣고 싶습니다!
만약 그렇다면, 다음을 문의하고 싶습니다:

  • 이것이 실제로 왜 필요한지, 그리고
  • 이에 대해 계획 중인 조치가 무엇인지 (이것은 분명 이상적이지 않으며, 이것이 예상된 동작이 아니어야 하는 이유에 대한 제 1번 항목을 참조하십시오)

감사합니다!

안녕하세요 @smileBeda,

문서화는 다음 링크에서 확인하실 수 있습니다:

사용자가 포럼의 어떤 경로를 방문하든 자동으로 로그인으로 리다이렉트되기를 원하신다면 login required(로그인 필요) 설정을 활성화해야 합니다. 이는 실제로 기대되는 동작입니다.

@angus 님, 확인해 주셔서 감사합니다.

여전히 어색하게 느껴지긴 하지만, wp에서 사용자가 로그인할 때 session/sso?return_path=로 리다이렉트하도록 추가했습니다.
return path는 wp의 referrer(있는 경우) 또는 wp 홈 페이지로 설정했습니다.

이 방식이 잘 작동하며, 사용자가 두 인스턴스 모두에 로그인되어 있는지 확인할 수 있습니다.
다만, discourse에서는 기본적으로 “외부” return path를 허용하지 않으므로, "모든 return path"를 허용하도록 설정을 활성화해야 했습니다.

이 설정을 활성화하는 것에 대해 문제가 될 만한 점을 보시나요?

다시 한번 친절하게 답변해 주시고, “공식” 확인과 문서 링크를 제공해 주셔서 감사합니다!

보통 이런 식의 자동 리다이렉트를 클라이언트에게 권하지 않습니다. 왜 이것이 문제라고 느끼시는지 이해합니다. 이는 꽤 흔한 감정입니다. 하지만 표준 방식은 당신 사이트보다 크거나 더 큰 규모의 많은 사이트에서 잘 작동하고 있습니다. 또한 자동 리다이렉트는 일부 시나리오에서 작동하지 않을 수 있어 사용자 경험(UX)을 해칠 수 있습니다.

기대하시는 '한 번 로그인하면 모든 곳에서 자동으로 로그인’되는 방식은 Meta(예: Facebook에 로그인하면 Instagram에도 로그인됨)와 같은 상호 연결된 서비스가 중앙 집중식으로 제어되는 플랫폼이기 때문에 때때로 그렇게 작동하는 것입니다(비록 중앙 집중식 서비스조차도 DiscourseConnect와 동일한 방식으로 작동할 때가 있기는 합니다).

반면, 여기서는 독립적인 오픈소스 소프트웨어 프레임워크(즉, WordPress와 Discourse)를 다루고 있습니다. 기대하시는 방식으로 효과적으로 작동하도록 설정할 수는 있지만, 이는 특정 사용 사례를 고려한 구체적인 맞춤 작업이 필요합니다. 수천 가지의 다른 사용 사례를 지원하는 DiscourseConnect와 같은 인증 시스템이 작동하는 방식과는 결코 같을 수 없습니다.

아니요. 다만, 그것이 필요한 전제 자체를 의문시할 것입니다. 하지만 더 많은 정보가 없다면, 그것을 사용하는 데 문제는 보이지 않습니다.

여기에 설명된 것과 같은 무효화된 리다이렉트 리스크(invalidated redirect risk)일 수 있을까요?

"모든 반환 값을 허용"하는 것이 실제로 어디로든 리다이렉트할 수 있게 한다는 점은 이해합니다.
하지만 해당 리다이렉트 URL을 통해 민감한 데이터가 공유되지 않으므로 이것이 실제로 리스크가 될지는 확신할 수 없습니다.

감사합니다!

@Angus - 위에서 언급한 마지막 질문에 대해 혹시 통찰이나 조언을 주실 수 있을까요?

감사합니다!

죄송합니다. 직접 확인하지도 않고, 또 여러분과의 관계가 명확히 정의되지 않은 상태에서 설정의 민감한 부분에 대해 조언을 드리는 것은 적절하지 않겠습니다.

특히 여러분의 포럼 규모와 해당 포럼에 적용되는 관련 규정들을 고려할 때, 해당 문제에 대해 구체적이고 전문적인 조언을 구하시기를 권합니다.

아마도 명확하지 않았을 수 있습니다:

  1. Discourse 포럼은 discourse 설정에서 "모든 반환 경로(any return path)"를 허용하도록 활성화합니다.
  2. 이는 이제 your-discourse.tld/session/sso?return_path=아무거나 와 같은 주소를 방문할 수 있음을 의미합니다.
  3. '아무거나’는 외부 URL일 수 있습니다.

따라서 이는 적어도 피싱 시도를 수행할 수 있는 보안 취약점을 열어줍니다:

  • 악성 웹사이트가 "놀라운 커뮤니티로 가기!"라고 적힌 버튼을 만듭니다.
  • 버튼 링크는 your-discourse.tld/session/sso?return_path=악성 사이트로 돌아가기 입니다.
  • 사용자가 버튼을 누르면 커뮤니티에 로그인하고, 이는 사용자를 악성 사이트로 되돌려 보냅니다.
    -在那里, 악성 행위자는 커뮤니티와 완전히 똑같이 보이는 페이지를 구현하여 "로그인 중 문제가 발생했습니다. 다시 시도해 주세요"라고 표시합니다.
  • 사용자는 커뮤니티의 모습과 일치하는 그럴듯한 로그인 양식에 로그인 정보를 제출합니다.

악성 행위자가 이제 로그인 데이터를 탈취한 것입니까?

따라서 사용자가 로그인하는 사이트의 경우, 모든 사용자가 정확히 무엇을 주의해야 하는지 알고 있지 않는 한 “모든 반환 경로” 설정은 절대 사용되지 않아야 할 것입니다.

당신도 그 위험을 보시나요?
이 설정과 상호작용할 수 있는 플러그인/코드를 작성하는 Discourse 개발자들이 “예, 문제없습니다” 또는 "절대로 안 됩니다"라고 고개를 끄덕여줄 수 없는 이유는 무엇일까요?
그 URL 파라미터에서 변경될 수 있는 것은 그리 많지 않습니다. 존재하거나 존재하지 않는 것, 또는 외부 허용 여부를 결정하는 것뿐입니다.

아마도 제가 "여기서는 보안 문제를 논의하지 마세요"라는 영역에 손을 뻗고 있는 것일까요? 물론 이해합니다. 많은 플랫폼이 활성화되었을 때 명확히 정의되지 않은 잠재적 보안 문제에 대해 공개적으로 논의하는 것을 허용하지 않으니까요 :slight_smile:

이미 스스로에게 답을 했다고 생각합니다.

실제로 설정의 성질(긍정/부정)은 사용 방식에 따라 달라지기 때문입니다. 이것이 단순히 '기능’이 아니라 '설정’인 이유이기도 합니다. 만약 질문하신 내용에 대해 단순한 답이 있었다면, 애초에 설정 자체가 존재하지 않았을 것입니다.

이 다소 법률가적인 답변이 답답하게 느껴질 수 있다는 점은 이해합니다. 하지만 사용자에게 필요한 조언은 구체적인 사용 사례에 특화된 것이어야 하며, 저는 여기서 그 조언을 드릴 입장이 아닙니다.