ServiceStack混合身份验证方法,多个组织和方法AD FS2,openId,facebook,google

时间:2013-10-11 09:41:08

标签: openid servicestack adfs2.0 google-openid federated-identity

是否可以向servicestack添加多种身份验证方法?我有五个用户:

 1. User 1 (Facebook account, Organization 1)
 2. User 2 (Google account, Organization 1)
 3. User 3 (AD FS2, Organization 2, https://company2.com/adfs/ls/)
 4. User 4 (AD FS2, Organization 3, https://company3.de/adfs/ls/) 
 5. User 5 (AD FS2, Organization 3, https://company3.de/adfs/ls/)

应由用户电子邮件选择身份验证方法。所有用户都在一个组织中,电子邮件是唯一的。)

如何使用AD FS2对用户进行身份验证? 如何实现多个auth提供程序和方法?

1 个答案:

答案 0 :(得分:1)

我有类似的情况,单个用户可以从不同的来源登录,在我的情况下,他们可以从网站和社交网络登录,所有可能的身份验证的所有电子邮件登录应该是相同的。< / p>

我建议您为每种情况创建海关身份验证提供程序,并在每种登录方法中保留您需要的任何信息,以遵循您的身份验证逻辑。

在这种情况下,

可能类似于

 Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[]
{
                    container.Resolve<CustomFacebookProvider>(),
                    container.Resolve<CustomAuthProvider>(),
                    container.Resolve<CustomGoogleOpenIdOAuthProvider>(),
 }));

容器将解决您对任何自定义操作的任何依赖关系,您需要将您的persistance层合并到每个身份验证提供程序中,以运行您需要执行的任何逻辑以验证用户登录例如:

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 +等)应遵循相同的流程,至少这种方法对我来说很好。