diff --git a/BaronSoftware.SSO.Sample/MainWindow.xaml b/BaronSoftware.SSO.Sample/MainWindow.xaml
index 37deac1..ee5e4d8 100644
--- a/BaronSoftware.SSO.Sample/MainWindow.xaml
+++ b/BaronSoftware.SSO.Sample/MainWindow.xaml
@@ -18,14 +18,10 @@
FontSize="16" FontWeight="Bold" Margin="0,0,0,12"/>
-
-
-
-
+
+
+
+
diff --git a/BaronSoftware.SSO.Sample/MainWindow.xaml.cs b/BaronSoftware.SSO.Sample/MainWindow.xaml.cs
index 49a7533..d395002 100644
--- a/BaronSoftware.SSO.Sample/MainWindow.xaml.cs
+++ b/BaronSoftware.SSO.Sample/MainWindow.xaml.cs
@@ -1,11 +1,7 @@
-using BaronSoftware;
-using BaronSoftware.Auth;
using BaronSoftware.Auth.Sample;
-using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
-using System.Threading.Tasks;
using System.Windows;
namespace BaronSoftware.SSO.Sample
@@ -23,11 +19,22 @@ namespace BaronSoftware.SSO.Sample
InitializeComponent();
_settings = SampleSettings.Load();
- ApplySettings();
- }
- /// 현재 설정으로 SSO 클라이언트를 (재)생성한다.
- private void ApplySettings() => _license = new BaronSSO(_settings.ToOidcOptions());
+ 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)
{
@@ -41,10 +48,21 @@ namespace BaronSoftware.SSO.Sample
_settings.Oidc.ClientId = dlg.ClientId;
_settings.Oidc.RedirectUri = dlg.RedirectUri;
_settings.Oidc.LogoutUri = dlg.LogoutUri;
+
try
{
_settings.Save();
- ApplySettings();
+
+ 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" +
@@ -59,8 +77,6 @@ namespace BaronSoftware.SSO.Sample
}
}
- private async void LoginButton_Click(object sender, RoutedEventArgs e)
- => await RunAsync("웹뷰 로그인", () => _license.SignInAsync());
private async void LogoutButton_Click(object sender, RoutedEventArgs e)
{
@@ -80,7 +96,7 @@ namespace BaronSoftware.SSO.Sample
}
}
- private async Task RunAsync(string action, Func work)
+ private async Task RunLogin(string action, Func work)
{
SetBusy(true);
OutputBox.Text = $"{action} 진행 중...";
@@ -88,7 +104,7 @@ namespace BaronSoftware.SSO.Sample
{
await work();
OutputBox.Text = $"{action} 완료 ✔\n\n";
- OutputBox.Text += Format(_license.CurrentUser);
+ OutputBox.Text += ShowLoginUserInfo(_license.CurrentUser);
OutputBox.CaretIndex = 0; // 맨 위(요약)부터 보이도록
}
catch (OperationCanceledException)
@@ -105,10 +121,10 @@ namespace BaronSoftware.SSO.Sample
}
}
- private void SetBusy(bool busy)
- => LoginButton.IsEnabled = LogoutButton.IsEnabled = !busy;
+ private void SetBusy(bool busy)=> LoginButton.IsEnabled = LogoutButton.IsEnabled = !busy;
- private string Format(UserInfo u)
+ // For Display=============
+ private string ShowLoginUserInfo(UserInfo u)
{
var sb = new StringBuilder();
sb.AppendLine("로그인 성공 ✔");
@@ -150,6 +166,9 @@ namespace BaronSoftware.SSO.Sample
catch { return json; }
}
- private async void TokenLoginBuggon_Click(object sender, RoutedEventArgs e) => await RunAsync("토큰 로그인", () => _license.SignInAsync(_license.CurrentUser.RefreshToken));
+ // ================
+
+
+
}
}
diff --git a/BaronSoftware.SSO.Sample/SampleSettings.cs b/BaronSoftware.SSO.Sample/SampleSettings.cs
index 4a44d96..2f85d00 100644
--- a/BaronSoftware.SSO.Sample/SampleSettings.cs
+++ b/BaronSoftware.SSO.Sample/SampleSettings.cs
@@ -73,7 +73,7 @@ namespace BaronSoftware.Auth.Sample
Authority = Oidc.Authority,
ClientId = Oidc.ClientId,
RedirectUri = Oidc.RedirectUri,
- Validator = new SimpleUserValidator()
+ ExtraUserValidator = new SimpleUserValidator()
};
}
}
diff --git a/BaronSoftware.SSO.Sample/SimpleUserValidator.cs b/BaronSoftware.SSO.Sample/SimpleUserValidator.cs
index 4cd3153..3635fca 100644
--- a/BaronSoftware.SSO.Sample/SimpleUserValidator.cs
+++ b/BaronSoftware.SSO.Sample/SimpleUserValidator.cs
@@ -3,15 +3,15 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using BaronSoftware.SSO;
namespace BaronSoftware.SSO.Sample
{
internal class SimpleUserValidator : IUserValidator
{
- public bool Validate(UserInfo user)
+ public void Validate(UserInfo user)
{
- // 가족사 아니면 거절
- return false;
+ throw new InvalidUserException("user is not family member");
}
}
}
diff --git a/BaronSoftware.SSO/BaronSSO.cs b/BaronSoftware.SSO/BaronSSO.cs
index f0805be..dc24e49 100644
--- a/BaronSoftware.SSO/BaronSSO.cs
+++ b/BaronSoftware.SSO/BaronSSO.cs
@@ -1,5 +1,3 @@
-using BaronSoftware.SSO.Exceptions;
-
namespace BaronSoftware.SSO
{
///
@@ -36,37 +34,45 @@ namespace BaronSoftware.SSO
}
/// 웹뷰 로그인 창을 띄워 인증합니다.
- public async Task SignInAsync() => await SignInAsync(null);
+ public async Task SignInAsync()
+ {
+ UserInfo? user = null;
+ if (option.EnableAutoLogin)
+ user = UserInfo.FromSsoFile();
+
+ await SignInAsync(user?.RefreshToken);
+ }
- /// 웹뷰 로그인 창을 띄워 인증합니다.
public async Task SignInAsync(string refreshToken)
{
UserInfo user = null;
- if(option.EnableAutoLogin)
- user = UserInfo.FromSsoFile();
-
var isConnected = await CheckConnection();
- if(!isConnected && option.EnableOffline)
+ if (isConnected)
{
+ var token = await client.LoginAsync(refreshToken);
+ var userJson = await client.GetUserInfoAsync(token.AccessToken);
+ if (string.IsNullOrEmpty(userJson))
+ throw new InvalidOperationException($"Failed to get userinfo : {token.ToString()}");
+
+ user = UserInfo.FromJson(userJson, token);
if (user == null)
- throw new InvalidUserException("Not found authorized last user.");
- option?.Validator?.Validate(user);
- return;
+ throw new InvalidUserException($"Broken user token. Token {token.ToString()}, UserJson {userJson}");
+ }
+ else
+ {
+ if (!option.EnableOffline)
+ throw new InvalidOperationException("Network isn't available.");
+
+ user = UserInfo.FromSsoFile();
+ if (user == null)
+ throw new InvalidUserException("Not found sso data for offline.");
}
- var token = await client.LoginAsync(refreshToken);
- var userJson = await client.GetUserInfoAsync(token.AccessToken);
- if (string.IsNullOrEmpty(userJson))
- throw new InvalidOperationException($"Failed to get userinfo : {token.ToString()}");
-
- user = UserInfo.FromJson(userJson, token);
-
- if (user == null || option?.Validator == null)
- throw new NullReferenceException("user or validator option is null");
-
// 가족사가 아니고, 인증도 실패 시
- if(!user.IsFamily()&& !option.Validator.Validate(user))
- throw new InvalidUserException("Failed to authorize user");
+ if (user.IsFamily())
+ option?.FamilyValidator?.Validate(user);
+ else
+ option?.ExtraUserValidator?.Validate(user);
CurrentUser = user;
CurrentUser.Save();
diff --git a/BaronSoftware.SSO/BaronSSOOption.cs b/BaronSoftware.SSO/BaronSSOOption.cs
index dc755ff..1ab4bb8 100644
--- a/BaronSoftware.SSO/BaronSSOOption.cs
+++ b/BaronSoftware.SSO/BaronSSOOption.cs
@@ -38,9 +38,16 @@ namespace BaronSoftware.SSO
///
public bool EnableAutoLogin { get; set; } = true;
+ private IUserValidator familyValidator;
+ public IUserValidator FamilyValidator
+ {
+ get => familyValidator ?? new DefaultFamilyUserValidator();
+ set => familyValidator = value;
+ }
+
///
/// 사용자 인증에 대한 추가 검증이 필요한 경우, IUserValidator 인터페이스를 구현하여 Validator 속성에 할당할 수 있습니다.
///
- public required IUserValidator? Validator { get; set; }
+ public required IUserValidator? ExtraUserValidator { get; set; }
}
}
diff --git a/BaronSoftware.SSO/Exceptions/InvalidUserException.cs b/BaronSoftware.SSO/Exceptions/InvalidUserException.cs
index 53ed86c..212bd91 100644
--- a/BaronSoftware.SSO/Exceptions/InvalidUserException.cs
+++ b/BaronSoftware.SSO/Exceptions/InvalidUserException.cs
@@ -4,10 +4,13 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace BaronSoftware.SSO.Exceptions
+namespace BaronSoftware.SSO
{
- internal class InvalidUserException : Exception
- {
+ public class InvalidUserException : Exception
+ {
+ public UserInfo userinfo { get; }
+
+ public InvalidUserException(UserInfo userinfo) { }
public InvalidUserException() { }
public InvalidUserException(string message) : base(message) { }
public InvalidUserException(string message, Exception inner) : base(message, inner) { }
diff --git a/BaronSoftware.SSO/Features/Validator/DefaultFamilyUserValidator.cs b/BaronSoftware.SSO/Features/Validator/DefaultFamilyUserValidator.cs
new file mode 100644
index 0000000..c8b96f9
--- /dev/null
+++ b/BaronSoftware.SSO/Features/Validator/DefaultFamilyUserValidator.cs
@@ -0,0 +1,13 @@
+namespace BaronSoftware.SSO
+{
+ internal class DefaultFamilyUserValidator : IUserValidator
+ {
+ public void Validate(UserInfo user)
+ {
+ if (user.IsCenter() || user.IsFamily())
+ return;
+
+ throw new InvalidUserException(user);
+ }
+ }
+}
diff --git a/BaronSoftware.SSO/Features/Validator/IUserValidator.cs b/BaronSoftware.SSO/Features/Validator/IUserValidator.cs
index a68c0a8..ecb0244 100644
--- a/BaronSoftware.SSO/Features/Validator/IUserValidator.cs
+++ b/BaronSoftware.SSO/Features/Validator/IUserValidator.cs
@@ -5,9 +5,10 @@ namespace BaronSoftware.SSO
public interface IUserValidator
{
///
- /// 인증 실패 시 예외를 던지세요
+ /// 사용자 인증 처리기.
+ /// 인증 실패 시, 반드시 예외를 던져서 처리하세요
///
///
- public bool Validate(UserInfo user);
+ public void Validate(UserInfo user);
}
}