Hosting environment.impersonate is not woking with System.DirectoryServices.AccountManagement on the server - directoryservices

Hi I want to retrieve the groups belonging to logged in user I tried following code but it is not working on the server.
using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
string userName = HttpContext.Current.User.Identity.Name;
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
UserPrincipal User = new UserPrincipal(domain);
User = UserPrincipal.FindByIdentity(domain, userName);
var strUnAuthorised = "";
if (User != null)
{
PrincipalSearchResult<Principal> gp = User.GetGroups();
foreach (Principal p in gp)
{
if (p.DisplayName == "xyz")
{
IsInGroup = true;
break;
}
}
}
}
after this when I am trying to read one xml file from the server I am getting not authorised error. please help me I am struggling alot

Related

vulnerability from security team in forget password controller in asp .net

I have a controller form application and the security team they said there is a vulnerability you can put any user_id fom postman inside the controller like this
ForgotPassword/user_id
how I can remove this vulnerability check the code below:
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult ForgotPassword(string emailId)
{
var helper = new Helper.Helper();
List<SqlParameter> args = new List<SqlParameter>();
args.Add(new SqlParameter("#Pin_email_id", emailId));
var req_resp = new Dictionary<string, object>();
try
{
using (DataSet dataset = helper.ExecuteSqlQuery("Web_Forgot_Password", args))
{
if (dataset != null && dataset.Tables.Count > 0 && dataset.Tables[0].Rows.Count > 0)
{
if (dataset.Tables[0].Rows[0]["Status"].ToString() == "Success")
{
req_resp["status"] = true;
req_resp["message"] = dataset.Tables[0].Rows[0]["Description"].ToString();
req_resp["code"] = dataset.Tables[0].Rows[0]["Code"].ToString();
string password = dataset.Tables[0].Rows[0]["user_password"].ToString();
SendForgotMail(emailId, dataset.Tables[0].Rows[0]["user_name"].ToString(), helper.Decrypt(password), dataset.Tables[0].Rows[0]["employee"].ToString());
return Json(req_resp);
}
else
{
req_resp["status"] = false;
req_resp["message"] = dataset.Tables[0].Rows[0]["Description"].ToString();
req_resp["code"] = dataset.Tables[0].Rows[0]["Code"].ToString();
return Json(req_resp);
}
}
else
{
req_resp["status"] = false;
req_resp["message"] = "Request Failed";
req_resp["code"] = "1005";
return Json(req_resp);
}
}
}
catch
{
var response = new
{
status = false,
message = "Request failed",
code = "1005"
};
return Json(response);
}
}
Well normally you store only password hashes in your database, which are not decryptable. Watching helper.Decrypt(password) in your code and sending the original password as a plain text in email is something painful. Normally I would just send a password reset link which can be used only once.
I checked the SqlParemater docs, it is added as a String value the way you use it, so it is not SQL injectable. Without the exact SQL I cannot tell much. I think they meant that it is SQL injectable, but then they should send evidence at least.

Active Directory Searching on Mac OS with .Net Core

I have recently moved from a Windows machine to a Mac and developing in ASP.Net Core.
I currently use the following code when testing on the Windows machine to look up users :
User LookupAdUser(String logon)
{
if (String.IsNullOrEmpty(logon))
return null;
User user = null;
string domain = Environment.UserDomainName;
PrincipalContext ctx = null;
try
{
int index = logon.IndexOf(#"\");
if (index > 0)
{
// a domain has been specified so get information from that domain
domain = logon.Substring(0, index);
logon = logon.Substring(index + 1);
ctx = new PrincipalContext(ContextType.Domain, domain);
}
else
{
ctx = new PrincipalContext(ContextType.Domain);
}
UserPrincipal principal = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, logon);
if (principal != null)
{
user = new User
{
Logon = String.Format(#"{0}\{1}", domain, logon),
Email = principal.EmailAddress,
UserName = principal.EmailAddress,
EmailConfirmed = true,
Active = true
};
}
}
catch (Exception ex)
{
//Logger.Error(string.Format("Failed to lookup the user ({0}) in AD...creating an empty User object", logon), ex);
Debug.WriteLine(ex);
}
finally
{
if (ctx != null)
ctx.Dispose();
}
return user;
}
When moving to the Macbook and testing the same code I get the error :
Exception thrown: 'System.PlatformNotSupportedException' in System.DirectoryServices.AccountManagement.dll
Is there any work around to this for the mac os to still tap into the active directory? or is just this not possible on mac?

Prevent multiple login in asp.net MVC 4 application

A system need single user login at a time. If tried for multiple login simultaneously the user get blocked. I have used Cookie Authentication which will manage from client browser.
Login Code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel oLoginViewModel)
{
try
{
bool Result = new UserBL().ValidateUser(oLoginViewModel.UserName, oLoginViewModel.Password);
if (Result == true)
{
FormsService.SignIn(oLoginViewModel.UserName, oLoginViewModel.RememberMe);
CreateAuthenticationTicket(oLoginViewModel.UserName);
return RedirectToLocal(Request.Form["returnUrl"]);
}
else
ViewBag.Error = "Invalid Username or Password / Due to simultaneous login you get blocked.";
return View();
}
catch (Exception ex)
{
throw ex;
}
}
public void CreateAuthenticationTicket(string username)
{
Users oUsers = new Users();
oUsers.Email = username;
oUsers.Role = "User";
int sessionid = new UserBL().GetByUserName(username).UserId;
string userData = JsonConvert.SerializeObject(oUsers);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
username,
DateTime.Now,
DateTime.Now.AddYears(1), // value of time out property
false, //pass here true, if you want to implement remember me functionality
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
var isSsl = Request.IsSecureConnection; // if we are running in SSL mode then make the cookie secure only
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
{
HttpOnly = false,
Secure = isSsl,
};
faCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(faCookie);
//Login Repository Entry
LoginsRepository oLogin = new LoginsRepository();
oLogin.UserName = username;
oLogin.SessionId = sessionid.ToString();
oLogin.LoggedIn = true;
oLogin.CreatedOn = Utility.CommonFunction.DateTime_Now();
oLogin.IPAddress = HttpContext.Request.RequestContext.HttpContext.Request.ServerVariables["REMOTE_ADDR"];
oLogin.Status = En_LoginStatus.SingleUser.ToString();
new LoginRepositoryBL().Add(oLogin);
}
I'm saving every user login with their IP Address to check the user multiple login.
After login it redirects to home controller and their I checked the multiple logins logic from database table Loginsrepository which is mentioned above :
public class HomeController : CustomerBaseController
{
public ActionResult Index()
{
Users oUser = new Users();
oUser = new UserBL().getActiveUser();
// check to see if your ID in the Logins table has
// LoggedIn = true - if so, continue, otherwise, redirect to Login page.
if (new LoginRepositoryBL().IsYourLoginStillTrue(System.Web.HttpContext.Current.User.Identity.Name, oUser.UserId.ToString()))
{
// check to see if your user ID is being used elsewhere under a different session ID
if (!new LoginRepositoryBL().IsUserLoggedOnElsewhere(System.Web.HttpContext.Current.User.Identity.Name, oUser.UserId.ToString()))
{
Answers oAnswer = new Answers();
return View(oAnswer);
}
else
{
// if it is being used elsewhere, update all their
// Logins records to LoggedIn = false, except for your session ID
new LoginRepositoryBL().LogEveryoneElseOut(System.Web.HttpContext.Current.User.Identity.Name, oUser.UserId.ToString());
Answers oAnswer = new Answers();
return View(oAnswer);
}
}
else
{
oUser = new UserBL().GetByUserName(System.Web.HttpContext.Current.User.Identity.Name);
oUser.Status = En_Status.Inactive.ToString();
new UserBL().update(oUser);
FormsService.SignOut();
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
}
}
Above methods :
public bool IsYourLoginStillTrue(string userId, string sid)
{
try
{
using (var ctx = new CnSiteEntities())
{
IEnumerable<LoginsRepository> logins = (from i in ctx.LoginsRepository
where i.LoggedIn == true &&
i.UserName == userId && i.SessionId == sid
select i).AsEnumerable();
return logins.Any();
}
}
catch (Exception)
{
throw;
}
}
public bool IsUserLoggedOnElsewhere(string userId, string sid)
{
try
{
using (var ctx = new CnSiteEntities())
{
IEnumerable<LoginsRepository> logins = (from i in ctx.LoginsRepository
where i.LoggedIn == true &&
i.UserName == userId && i.SessionId != sid
select i).AsEnumerable();
return logins.Any();
}
}
catch (Exception)
{
throw;
}
}
public void LogEveryoneElseOut(string userId, string sid)
{
try
{
using (var ctx = new CnSiteEntities())
{
IEnumerable<LoginsRepository> logins = (from i in ctx.LoginsRepository
where i.LoggedIn == true &&
i.UserName == userId &&
i.SessionId != sid // need to filter by user ID
select i).AsEnumerable();
foreach (LoginsRepository item in logins)
{
item.LoggedIn = false;
}
ctx.SaveChanges();
}
}
catch (Exception)
{
throw;
}
}
It's not working properly. It keeps it true after login even if multiple simultaneous logins. I have googled it and tried it much but I didn't get any solution.

ASP.Net Core : get members of Active Directory group

I'm wondering how I could get a list of members of an AD group.
Checking if an entered password of a user is correct works perfectly fine. For this I'm using Novell's Ldap.NetStandard:
private bool IsUserValid(string userName,string userPassword)
{
try{
using (var connection = new LdapConnection { SecureSocketLayer = false })
{
connection.Connect("test.local", LdapConnection.DEFAULT_PORT);
connection.Bind(userDn, userPassword);
if (connection.Bound)
{
return true;
}
}
}
catch (LdapException ex)
{
Console.WriteLine(ex.Massage);
}
return false;
}
What I want now is something like this:
bool isUserInGroup("testUser","testGroup");
The problem is I can't get my method working:
public bool IsUserMemberOfGroup(string userName,string groupName)
{
var ldapConn = GetConnection();
var searchBase = "";
var filter = $"(&(objectClass=group)(cn={groupName}))";
var search = ldapConn.Search(searchBase, LdapConnection.SCOPE_BASE, filter, null, false);
while (search.hasMore())
{
var nextEntry = search.next();
if (nextEntry.DN == userName)
return true;
}
return false;
}
What ever I'm doing, I'm not getting back any value from my Ldap.Search()...
Now there is an implementation of System.DirectoryServices.AccountManagement for .NET Core 2. It is available via nuget.
With this package you are able to things like that:
using (var principalContext = new PrincipalContext(ContextType.Domain, "YOUR AD DOMAIN"))
{
var domainUsers = new List<string>();
var userPrinciple = new UserPrincipal(principalContext);
// Performe search for Domain users
using (var searchResult = new PrincipalSearcher(userPrinciple))
{
foreach (var domainUser in searchResult.FindAll())
{
if (domainUser.DisplayName != null)
{
domainUsers.Add(domainUser.DisplayName);
}
}
}
}
This performs a search for the user in your domain.Nearly the same is possible for searching your group. The way I used to search my AD (description in my question) is now obsolet:
Checking if an entered password of a user is correct works perfectly
fine. For this I'm using Novell's Ldap.NetStandard:
How about:
HttpContext.User.IsInRole("nameOfYourAdGroup");
(namespace System.Security.Claims)

Login users at the same time problems in signalr

I'm working on a social network with ASP.NET and signalr. I have a simple login page, if it finds the user in the database it creates an Application variable and redirect the user to the profile page and in this page i invoke my Connect method declared in my hub class, this method takes the userid in the session and it give the friend list of this user. That works great when two or many users logged in at different time. The thing is, when two or several users logged in at the same time, the connect method declared in my hub takes the last user id stored in the Application variable and it give the friend list of this last user id and it send it to all user connected.
I can't find the correct approach.
Loggin Page code:
protected void btn_login_Click(object sender, EventArgs e)
{
Tbl_User user = new Tbl_User();
user = FonctionCommun.Login(txt_UserName.Text , txt_PassWord.Text);
if (user != null)
{
Application["UserID"] = user.UserID.ToString();
Response.Redirect("Profile.aspx");
}
else {
Label1.Visible = true;
}
}
My connect method code:
public void connect()
{
UserID = Guid.Parse(HttpContext.Current.Application["UserID"].ToString());
string OutPut = "";
if (ListOnlineUser.Count(x => x.UserID == UserID) == 0)
{
ListOnlineUser.Add(new OnlineUsers { UserID = UserID, ConnetionID = Guid.Parse(Context.ConnectionId) });
objchat.SetOnline(UserID);
ListFriends = objchat.GetFriendLoginStatus(UserID);
}
foreach (Tbl_User item in ListFriends)
{
if (item.Status == "1")
{
OnlineUsers onlineFriend = ListOnlineUser.FirstOrDefault(x => x.UserID == Guid.Parse(item.UserID.ToString()));
if (onlineFriend != null)
{
using (FIESTA_ADVISOREntities BD = new FIESTA_ADVISOREntities())
{
Tbl_User Obj_User = BD.Tbl_User.Where(o => o.UserID == UserID).FirstOrDefault();
if (Obj_User.ProfileImage != null)
{
string ext = BD.Assets.Where(o => o.url == Obj_User.ProfileImage).Select(o => o.MimeType).FirstOrDefault();
UserDetaille res = new UserDetaille() { UserID = Guid.Parse(Obj_User.UserID.ToString()), Username = Obj_User.UserName, ProfileImage = Obj_User.ProfileImage.ToString(), Ext = ext };
OutPut = JsonConvert.SerializeObject(res);
}
else {
UserDetaille res = new UserDetaille() { UserID = Guid.Parse(Obj_User.UserID.ToString()), Username = Obj_User.UserName, ProfileImage = "111", Ext = "png" };
OutPut = JsonConvert.SerializeObject(res); }
Clients.Client(onlineFriend.ConnetionID.ToString()).OnNewUserConnect(OutPut);
}
}
}
}
Clients.Caller.ShowFriends(ListFriends);
}
Try session variable instead of application variable. Application variable shared through out application working. So Whenever new user this is override. But if you use session variable that will never override by any other user
Also you can use query string in signalr in which you can pass userid as query string so in each request userid will be in query string
$.connection.hub.qs = 'userid=' + "UserId";

Resources