1 人のユーザーがさまざまなソースからログインできる同様の状況があります。私の場合、サイトからもソーシャル ネットワークからもログインできます。ログインが可能なすべての認証のすべての電子メールは同じである必要があります。
ケースごとにカスタム認証プロバイダーを作成し、各ログイン方法で必要な情報を保持して、認証ロジックに従うことをお勧めします。
この場合、次のようなものになる可能性があります
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[]
{
container.Resolve<CustomFacebookProvider>(),
container.Resolve<CustomAuthProvider>(),
container.Resolve<CustomGoogleOpenIdOAuthProvider>(),
}));
コンテナーは、カスタム操作の依存関係を解決します。たとえば、ユーザーのログインを検証するために必要なロジックを実行するには、永続化レイヤーを認証プロバイダーのそれぞれに組み込む必要があります。
public class CustomAuthProvider : CredentialsAuthProvider
{
public new static string Name = AuthService.CredentialsProvider;
public new static string Realm = "/auth/" + AuthService.CredentialsProvider;
private readonly IUserRepository _userRepository; // custom repo
public CustomAuthProvider(IUserRepository userRepository, IResourceManager appSettings)
: base(appSettings)
{
_userRepository = userRepository;
CallbackUrl = appSettings.GetString("oauth.{0}.CallbackUrl".Fmt(Name));
RedirectUrl = appSettings.GetString("oauth.{0}.RedirectUrl".Fmt(Name));
SessionExpiry = DefaultSessionExpiry;
}
public override object Authenticate(IServiceBase authService, IAuthSession session,
ServiceStack.ServiceInterface.Auth.Auth request)
{
string userName = request.UserName;
string password = request.Password;
if (!LoginMatchesSession(session, userName))
{
authService.RemoveSession();
session = authService.GetSession();
}
if (TryAuthenticate(authService, userName, password))
{
authService.SaveSession(session, SessionExpiry);
if (session.UserAuthName == null)
session.UserAuthName = userName;
OnAuthenticated(authService, session, null, null);
return new AuthResponse
{
UserName = userName,
SessionId = session.Id,
ReferrerUrl = RedirectUrl
};
}
throw new HttpError(HttpStatusCode.BadRequest, "400", "Invalid username or password");
}
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
IAuthSession session = authService.GetSession();
User user = _userRepository.GetByUserName(userName);
if ( _userRepository.login(username,password)) //or any other validation logic here
{
session.IsAuthenticated = true;
session.UserAuthId = string.Format("{0}", user.Id);
session.Id = authService.GetSessionId();
session.LastModified = user.LastLoginDate;
session.DisplayName = user.DisplayName;
session.Email = user.Email;
session.UserName = user.UserName;
user.LastLoginDate = DateTime.Now;
_userRepository.Update(user); //custom logic
return true;
}
return false;
}
facebook、google+ などの他のカスタム プロバイダーも同じプロセスに従う必要があります。少なくとも、このアプローチは私にとってはうまくいきました。