using System.Globalization; using System.Collections.Generic; using ServiceStack.Common; using ServiceStack.Common.Web; using ServiceStack.ServiceHost; using ServiceStack.Configuration; using ServiceStack.FluentValidation; namespace ServiceStack.ServiceInterface.Auth { public class CredentialsAuthProvider : AuthProvider { class CredentialsAuthValidator : AbstractValidator { public CredentialsAuthValidator() { RuleFor(x => x.UserName).NotEmpty(); RuleFor(x => x.Password).NotEmpty(); } } public static string Name = AuthService.CredentialsProvider; public static string Realm = "/auth/" + AuthService.CredentialsProvider; public CredentialsAuthProvider() { this.Provider = Name; this.AuthRealm = Realm; } public CredentialsAuthProvider(IResourceManager appSettings, string authRealm, string oAuthProvider) : base(appSettings, authRealm, oAuthProvider) { } public CredentialsAuthProvider(IResourceManager appSettings) : base(appSettings, Realm, Name) { } public virtual bool TryAuthenticate(IServiceBase authService, string userName, string password) { var authRepo = authService.TryResolve(); if (authRepo == null) { Log.WarnFormat("Tried to authenticate without a registered IUserAuthRepository"); return false; } var session = authService.GetSession(); UserAuth userAuth = null; if (authRepo.TryAuthenticate(userName, password, out userAuth)) { session.PopulateWith(userAuth); session.IsAuthenticated = true; session.UserAuthId = userAuth.Id.ToString(CultureInfo.InvariantCulture); session.ProviderOAuthAccess = authRepo.GetUserOAuthProviders(session.UserAuthId) .ConvertAll(x => (IOAuthTokens)x); return true; } return false; } public override bool IsAuthorized(IAuthSession session, IOAuthTokens tokens, Auth request=null) { if (request != null) { if (!LoginMatchesSession(session, request.UserName)) return false; } return !session.UserAuthName.IsNullOrEmpty(); } public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request) { new CredentialsAuthValidator().ValidateAndThrow(request); return Authenticate(authService, session, request.UserName, request.Password); } protected object Authenticate(IServiceBase authService, IAuthSession session, string userName, string password) { if (!LoginMatchesSession(session, userName)) { authService.RemoveSession(); session = authService.GetSession(); } if (TryAuthenticate(authService, userName, password)) { if (session.UserAuthName == null) session.UserAuthName = userName; OnAuthenticated(authService, session, null, null); return new AuthResponse { UserName = userName, SessionId = session.Id, }; } throw HttpError.Unauthorized("Invalid UserName or Password"); } public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary authInfo) { var userSession = session as AuthUserSession; if (userSession != null) { LoadUserAuthInfo(userSession, tokens, authInfo); } var authRepo = authService.TryResolve(); if (authRepo != null) { if (tokens != null) { authInfo.ForEach((x, y) => tokens.Items[x] = y); session.UserAuthId = authRepo.CreateOrMergeAuthSession(session, tokens); } foreach (var oAuthToken in session.ProviderOAuthAccess) { var authProvider = AuthService.GetAuthProvider(oAuthToken.Provider); if (authProvider == null) continue; var userAuthProvider = authProvider as OAuthProvider; if (userAuthProvider != null) { userAuthProvider.LoadUserOAuthProvider(session, oAuthToken); } } var httpRes = authService.RequestContext.Get(); if (httpRes != null) { httpRes.Cookies.AddPermanentCookie(HttpHeaders.XUserAuthId, session.UserAuthId); } } authService.SaveSession(session, SessionExpiry); session.OnAuthenticated(authService, session, tokens, authInfo); } } }