using BaronSoftware.Auth.Sample; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Windows; namespace BaronSoftware.SSO.Sample { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private BaronSSO _license; private readonly SampleSettings _settings; public MainWindow() { InitializeComponent(); _settings = SampleSettings.Load(); var option = new BaronSSOOption() { Authority = _settings.Oidc.Authority, ClientId = _settings.Oidc.ClientId, RedirectUri = _settings.Oidc.RedirectUri, ExtraUserValidator = new SimpleUserValidator() }; _license = new BaronSSO(option); LoginButton.Click += async (s,e) => await RunLogin("웹뷰 로그인", () => _license.SignInAsync()); TokenLoginBuggon.Click += async (s,e) => await RunLogin("토큰 로그인", () => _license.SignInAsync(_license.CurrentUser.RefreshToken)); SettingsButton.Click += SettingsButton_Click; LogoutButton.Click += LogoutButton_Click; } private void SettingsButton_Click(object sender, RoutedEventArgs e) { var dlg = new SettingsWindow(_settings.Oidc.Authority, _settings.Oidc.ClientId, _settings.Oidc.RedirectUri, _settings.Oidc.LogoutUri) { Owner = this }; if (dlg.ShowDialog() != true) return; _settings.Oidc.Authority = dlg.Authority; _settings.Oidc.ClientId = dlg.ClientId; _settings.Oidc.RedirectUri = dlg.RedirectUri; _settings.Oidc.LogoutUri = dlg.LogoutUri; try { _settings.Save(); var option = new BaronSSOOption() { Authority = _settings.Oidc.Authority, ClientId = _settings.Oidc.ClientId, RedirectUri = _settings.Oidc.RedirectUri, ExtraUserValidator = new SimpleUserValidator() }; _license = new BaronSSO(option); OutputBox.Text = "설정 저장 완료 ✔ (appsettings.json)\n\n" + $"Authority : {_settings.Oidc.Authority}\n" + $"ClientId : {_settings.Oidc.ClientId}\n" + $"RedirectUri : {_settings.Oidc.RedirectUri}\n" + $"LogoutUri : {_settings.Oidc.LogoutUri}\n\n" + "‘웹뷰로 로그인’으로 적용된 설정을 테스트하세요."; } catch (Exception ex) { OutputBox.Text = $"설정 저장 실패:\n{ex.Message}"; } } private async void LogoutButton_Click(object sender, RoutedEventArgs e) { SetBusy(true); OutputBox.Text = "로그아웃 중... (토큰 + 세션 쿠키 삭제)"; try { await _license.SignOutAsync(); OutputBox.Text = "로그아웃 완료 ✔\n" + "- refresh_token 삭제\n" + "- WebView SSO 세션 쿠키 삭제\n" + "→ 다음 ‘웹뷰로 로그인’ 시 로그인 창이 다시 표시됩니다."; } finally { SetBusy(false); } } private async Task RunLogin(string action, Func work) { SetBusy(true); OutputBox.Text = $"{action} 진행 중..."; try { await work(); OutputBox.Text = $"{action} 완료 ✔\n\n"; OutputBox.Text += ShowLoginUserInfo(_license.CurrentUser); OutputBox.CaretIndex = 0; // 맨 위(요약)부터 보이도록 } catch (OperationCanceledException) { OutputBox.Text = $"{action} 취소됨 (로그인 창이 닫힘)."; } catch (Exception ex) { OutputBox.Text = $"{action} 실패:\n{ex.GetType().Name}: {ex.Message}"; } finally { SetBusy(false); } } private void SetBusy(bool busy)=> LoginButton.IsEnabled = LogoutButton.IsEnabled = !busy; // For Display============= private string ShowLoginUserInfo(UserInfo u) { var sb = new StringBuilder(); sb.AppendLine("로그인 성공 ✔"); sb.AppendLine($"UserId(sub) : {u.UUID}"); sb.AppendLine($"Name : {u.Name}"); sb.AppendLine($"Email : {u.Email}"); sb.AppendLine($"TenantIds : {string.Join(", ", u.AllTenantIds ?? Array.Empty())}"); sb.AppendLine($"Last Auth Time : {u.LastAuthTime}"); sb.AppendLine($"Claims Start------------ \n "); sb.AppendLine(string.Join("\n", u.Claims.Select(kv => $" {kv.Key}: {kv.Value}"))); sb.AppendLine($"\nClaims End------------ \n "); sb.AppendLine(!string.IsNullOrWhiteSpace(u.RefreshToken) ? "자동 로그인 : 사용 가능 (refresh_token 저장됨)" : "자동 로그인 : 불가 — 리프레시 토큰 없음"); sb.AppendLine(); sb.AppendLine("==== token 엔드포인트 응답 (원본) ===="); sb.AppendLine(PrettyJson(u.RawTokenResponse)); sb.AppendLine(); sb.AppendLine("==== userinfo 응답 ===="); sb.AppendLine(PrettyJson(u.Raw)); return sb.ToString(); } private static readonly JsonSerializerOptions PrettyJsonOptions = new() { WriteIndented = true, // 한글 등 비ASCII를 \uXXXX로 이스케이프하지 않고 그대로 표시 Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, }; /// JSON 문자열을 들여쓰기(pretty) 형태로 변환. 파싱 실패 시 원본 반환. private static string PrettyJson(string json) { if (string.IsNullOrWhiteSpace(json)) return json; try { return JsonNode.Parse(json)?.ToJsonString(PrettyJsonOptions) ?? json; } catch { return json; } } // ================ } }