Hi,
i have huge problems with my sessions, seems that the users logged in will have the same session.
- If i log in with UserA a session is created and the user can call different services and everything works fine.
- But when UserB loggs in on another computer that session is also been overwritten for UserA.
- This means that when UserA calls a service next time he will get the last logged in users info.
Can you maybe see if something is wrong in my code or maybe guide me of what is wrong?
Would be very appreciated!
Class AspnetMembershipAuthSession
public class AspnetMembershipAuthSession : AuthUserSession
{
private readonly IRoleProviderWrapper _roleProvider;
private readonly IUserAuthRepository _userRep;
public AspnetMembershipAuthSession(IRoleProviderWrapper roleProvider, IUserAuthRepository userRep)
{
_roleProvider = roleProvider;
_userRep = userRep;
}
[DataMember]
public Guid MembershipId { get; set; }
[DataMember]
//RegisteredUserId
public Guid CustomerId { get; set; }
[DataMember]
public Guid CompanyUserId { get; set; }
[DataMember]
public Guid CompanyId { get; set; }
public bool IsAdmin
{
get { return HasRole(Role.ApplicationAdmin, _userRep); }
}
public bool IsSuperAdmin
{
get { return HasRole(Role.SuperAdmin, _userRep); }
}
public bool IsAnyAdmin
{
get { return IsAdmin || IsSuperAdmin; }
}
public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens,
Dictionary<string, string> authInfo)
{
base.OnAuthenticated(authService, session, tokens, authInfo);
var authRepository = authService.TryResolve<IAuthRepository>();
var userAuth = authRepository.GetUserAuth(session, tokens);
var guids = userAuth.RefIdStr.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
MembershipId = Guid.Parse(guids[0]);
CustomerId = Guid.Parse(guids[1]);
if (guids.Length > 3)
{
CompanyUserId = Guid.Parse(guids[2]);
CompanyId = Guid.Parse(guids[3]);
}
// we want to save after we set the custom fields
authService.SaveSession(this, SessionFeature.DefaultSessionExpiry);
}
public override void OnLogout(IServiceBase authService)
{
var id = authService.GetSessionId();
authService.RemoveSession();
base.OnLogout(authService);
var id2 = authService.GetSessionId();
}
public override bool HasRole(string role, IAuthRepository authRepo)
{
//return Roles != null && Roles.Any(r => r.ToLowerInvariant() == role.ToLowerInvariant());
return _roleProvider.HasRole(UserName, role);
}
}
Class AspNetMembershipAuthRepository
public class AspNetMembershipAuthRepository : IUserAuthRepository
{
private IDbConnectionFactory _dbFactory { get; set; }
//private readonly IDbConnection _db;
private readonly IMembershipProviderWrapper _membershipProvider;
private readonly IRoleProviderWrapper _roleProvider;
// See https://github.com/ServiceStack/ServiceStack/blob/b6b89cb23a96e002d39894f70f6acdba9312ef51/src/ServiceStack.Authentication.RavenDb/RavenDbUserAuthRepository.cs
public AspNetMembershipAuthRepository(IMembershipProviderWrapper membershipProvider,
IRoleProviderWrapper roleProvider,
IDbConnectionFactory dbFactory)
{
_membershipProvider = membershipProvider;
_roleProvider = roleProvider;
_dbFactory = dbFactory;
}
public IUserAuth CreateUserAuth(IUserAuth newUser, string password)
{
throw new NotImplementedException();
}
public IUserAuth UpdateUserAuth(IUserAuth existingUser, IUserAuth newUser)
{
throw new NotImplementedException();
}
public void DeleteUserAuth(string userAuthId)
{
throw new NotImplementedException();
}
public IUserAuth GetUserAuth(string userAuthId)
{
throw new NotImplementedException();
}
public IUserAuth UpdateUserAuth(IUserAuth existingUser, IUserAuth newUser, string password)
{
throw new NotImplementedException();
}
public IUserAuthDetails CreateOrMergeAuthSession(IAuthSession authSession, IAuthTokens tokens)
{
throw new NotImplementedException();
}
public IUserAuth GetUserAuth(IAuthSession authSession, IAuthTokens tokens)
{
return GetUserAuthByUserName(authSession.UserAuthName);
}
public IUserAuth GetUserAuthByUserName(string userNameOrEmail)
{
var member = _membershipProvider.GetUser(userNameOrEmail, true);
// Roles
var roles = _roleProvider.GetRolesForUser(member.User.UserName).ToList();
var isAdminUser = roles.Contains(Role.ApplicationAdmin) ||
roles.Contains(Role.SuperAdmin);
return GetUserInfo(isAdminUser, member, roles);
}
public List<IUserAuthDetails> GetUserAuthDetails(string userAuthId)
{
return new List<IUserAuthDetails>();
}
public void LoadUserAuth(IAuthSession session, IAuthTokens tokens)
{
throw new NotImplementedException();
}
public void SaveUserAuth(IUserAuth userAuth)
{
throw new NotImplementedException();
}
public void SaveUserAuth(IAuthSession authSession)
{
throw new NotImplementedException();
}
public bool TryAuthenticate(Dictionary<string, string> digestHeaders, string privateKey, int nonceTimeOut,
string sequence, out IUserAuth userAuth)
{
throw new NotImplementedException();
}
public bool TryAuthenticate(string userName, string password, out IUserAuth userAuth)
{
if (_membershipProvider.ValidateUser(userName, password))
{
userAuth = GetUserAuthByUserName(userName);
if (userAuth != null)
{
// TODO: Can we set the membership cookie here maybe?
//FormsAuthentication.SetAuthCookie(userName, false);
return true;
}
}
userAuth = null;
return false;
}
private IUserAuth GetUserInfo(bool isAdminUser, IMembership membership, List<string> roles)
{
using (var Db = _dbFactory.Open())
{
var membershipId = (Guid)membership.ProviderUserKey;
var registeredUser = Db.Single<Customer>(u => u.MembershipId == membershipId);
var userAuth = new UserAuth();
userAuth.Roles = roles;
if (registeredUser != null)
{
userAuth.UserName = membership.User.UserName.ToLowerInvariant();
userAuth.FirstName = registeredUser.Firstname;
userAuth.LastName = registeredUser.Lastname;
userAuth.Email = registeredUser.Email;
userAuth.CreatedDate = membership.CreateDate;
userAuth.PhoneNumber = registeredUser.Phone;
userAuth.RefIdStr = string.Format("{0}:{1}",
membershipId,
registeredUser.Id);
};
// For admin users, get the applicationuser aswell
if (isAdminUser)
{
var applicationUser = Db.Single<CompanyUser>(u => u.MembershipId == membershipId);
if (applicationUser != null)
{
userAuth.UserName = userAuth.UserName ?? applicationUser.Email;
userAuth.FirstName = userAuth.FirstName ?? applicationUser.Firstname;
userAuth.LastName = userAuth.LastName ?? applicationUser.Lastname;
userAuth.Email = userAuth.Email ?? applicationUser.Email;
userAuth.PhoneNumber = userAuth.PhoneNumber ?? applicationUser.Phone;
userAuth.RefIdStr = string.Format("{0}:{1}:{2}:{3}",
membershipId,
registeredUser == null ? Guid.Empty : registeredUser.Id,
applicationUser.Id,
applicationUser.CompanyId);
}
return userAuth;
}
return userAuth;
}
}
}
Class MembershipProviderWrapper
public class MembershipProviderWrapper : IMembershipProviderWrapper
{
public IMembership GetUser(string userNameOrEmail, bool userIsOnline)
{
var user = Membership.Provider.GetUser(userNameOrEmail, userIsOnline);
return new MembershipWrapper
{
User = new MembershipUserWrapper
{
UserId = Guid.Parse(user.ProviderUserKey.ToString()),
UserName = user.UserName,
LastActivityDate = user.LastActivityDate
},
CreateDate = user.CreationDate,
ProviderUserKey = user.ProviderUserKey
};
}
public bool ValidateUser(string userName, string password)
{
return Membership.Provider.ValidateUser(userName, password);
}
public bool ValidatePasswordComplexity(string password)
{
return Regex.IsMatch(password, "(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,15})$");
}
public bool ChangePassword(string userName, string oldPassword, string newPassword)
{
var user = Membership.Provider.GetUser(userName, true);
return user.ChangePassword(oldPassword, newPassword);
}
public Guid CreateUser(string userName, string password)
{
var user = Membership.CreateUser(userName, password).ProviderUserKey;
return Guid.Parse(user.ToString());
}
}
public class MyCredentialsAuthProvider : CredentialsAuthProvider
{
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
{
var authResponse = (AuthenticateResponse) base.Authenticate(authService, session, request);
var user = ((BokaMera.API.ServiceInterface.Security.AspNetMembership.AspnetMembershipAuthSession)session);
user.Language = Thread.CurrentThread.CurrentUICulture.ToString();
//return your own class, but take neccessary data from AuthResponse
//return new
//{
// SessionId = authResponse.SessionId,
// UserName = authResponse.UserName,
// CompanyUserId = user.CompanyUserId,
// RegisteredUserId = user.RegisteredUserId,
// FirstName = user.FirstName,
// LastName = user.LastName,
// Language = user.Language,
// ReferrerUrl = authResponse.ReferrerUrl,
// SessionExpires = DateTime.Now
//};
return authResponse;
}
}