Rotativa ActionAsPdf giving 'Access is denied' without username & password.(Windows Authentication) - c#

Below is Code:
public ActionResult DownloadPdf(int id, int pid)
{
string userName, password = string.Empty;
userName = ConfigurationManager.AppSettings["AdminUsername"];
password = ConfigurationManager.AppSettings["AdminPassword"];
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && id > 0 && pid > 0)
{
var pdf = new Rotativa.ActionAsPdf("PdfPartial", new { id = id, pid = pid })
{
UserName=userName,
Password=password,
FileName = "AFE.pdf",
};
return pdf;
}
else
{
return new Rotativa.ActionAsPdf("PdfError")
{
FileName = "AFE.pdf",
};
}
}
I am using windows authentication with Active Directory. I don't want to use username and password in web.config.Is it any way to achieve this? It can be possible if there is any way to access specific mvc action anonymously while using windows authentication.

Related

SHA512 hashed credentials fail on validation

I got this register form where i get the user email and password and hash the password using SHA512
public Boolean IsRegistered(String email, String pass)
{
SHA512 shaM = new SHA512Managed();
if (pass.Length > 0 && email.Length > 0)
{
byte[] data = Encoding.UTF8.GetBytes(pass);
String encryptedpass = Encoding.UTF8.GetString(shaM.ComputeHash(data));
using (ModelContainer db = new ModelContainer())
{
//User usr = db.UserSet.Where(u => u.PasswordDigest == encryptedpass && u.Email == email).First();
int matches = (from u in bd.UserSet
where u.PasswordDigest == encryptedpass&& u.Email == email
select new
{
Id = u.Id
}
).Count();
if (matches > 0)
{
return true;
}
}
}
return false;
}
I use this method each time the user logs in and it works like a charm (i guess),
thing is when i prompt the user to change his/her password i cannot seem to be able to validate the old one here is what i try
I do the following to retrive the user data on the MyAccount form's constructor
User user;.
public MyAccount()
{
InitializeComponent();
try
{
using (ModelContainer db = new ModelContainer())
{
user = (from u in db.UserSet where u.Id == 2 select u).First();
txtName.Text = user.Name;
txtEmail.Text = user.Email;
}
}
catch (Exception x)
{
ErrorAlert error = new ErrorAlert("Error: " + x.Message);
error.Owner = getParentWindow();
error.ShowDialog();
}
}
then I validate it on the forms button_click
using (ModelContainer db = new ModelContainer())
{
SHA512 shaM = new SHA512Managed();
string oldpass = Encoding.UTF8.GetString(shaM.ComputeHash(Encoding.UTF8.GetBytes(ptxtOldPassword.Password)));
shaM.Dispose();
db.UserSet.Attach(user);
Regex rgx = new Regex(#"\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z");
if (rgx.IsMatch(txtEmail.Text))
{
if (oldpass == user.PasswordDigest)
{
if (ptxtNewPassword.Password.Equals(ptxtNewPassword2.Password))
{
string newpass = Encoding.UTF8.GetString(shaM.ComputeHash(Encoding.UTF8.GetBytes(ptxtNewPassword.Password)));
user.Name = txtName.Text;
user.Email = txtEmail.Text;
user.PasswordDigest = newpass;
db.SaveChanges();
}
else
{
ErrorAlert error = new ErrorAlert("Passwords do not match");
error.Owner = getParentWindow();
error.ShowDialog();
}
When I comapare the old password in the database with the one the user enter they do not match since they are strings I've tried using equals with no luck I thought == would work but I was wrong, i looked into other answers and found this Sha512 not returning equal in c# hash validation sadly it didn't work for me, I need to understand why my first validation work and the second doesnt
so any help is apreciated Have a nice day
You don't really need to compare the final strings, test at the bytes-level. Check this previous question.
Also, if you already validated the existence of the user (by email or any other mechanism), why don't just change / update with the new password? You could validate with the email and re-use the working function for login / signin.

How to get user's password expiration date from Active Directory?

I have implemented implemented Active Directory authentication in ASP.NET MVC 5 using LDAP. I want to know how to get a user's
Account Locked (boolean)
Password Expired (boolean)
Password Expiry Date (DateTime)
This is my current code:
using System.Web.Mvc;
using System.Web.Security;
using MvcApplication.Models;
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (!this.ModelState.IsValid)
{
return this.View(model);
}
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (this.Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return this.Redirect(returnUrl);
}
return this.RedirectToAction("Index", "Home");
}
this.ModelState.AddModelError(string.Empty, "The user name or password provided is incorrect.");
return this.View(model);
}
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return this.RedirectToAction("Index", "Home");
}
The easiest way is to PInvoke LogonUser Win32 API.e.g
http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html
Read also MSDN reference: https://msdn.microsoft.com/en-us/library/aa378184.aspx
The examples for your questions: https://www.codeproject.com/articles/18102/howto-almost-everything-in-active-directory-via-c
I manage to do it using a combination of System.Web.Security and System.DirectoryServices.
public bool IsExpired(MembershipUser user, LoginModel model)
{
bool result = false;
string ldap = ConfigurationManager.ConnectionStrings["ADConnectionString"].ConnectionString;
DirectoryEntry rootEntry = new DirectoryEntry(ldap, model.UserName, model.Password, AuthenticationTypes.Secure);
DirectorySearcher mySearcher = new DirectorySearcher(rootEntry);
SearchResultCollection results;
string filter = "maxPwdAge=*";
mySearcher.Filter = filter;
results = mySearcher.FindAll();
long maxDays = 0;
if (results.Count >= 1)
{
Int64 maxPwdAge = (Int64)results[0].Properties["maxPwdAge"][0];
maxDays = maxPwdAge / -864000000000;
}
long daysLeft = 0;
daysLeft = maxDays - DateTime.Today.Subtract(user.LastPasswordChangedDate).Days;
if (daysLeft <0)
{
result = true;
} else
{
if (daysLeft<=14)
{
this.Expiring = true;
this.ExpiringString = String.Format("You must change your password within" + " {0} days", daysLeft);
}
else
{
this.Expiring = false;
}
}
return result;
}
Here's another approach to getting the user's account password expiration date, and from the result you can easily calculate IsExpired:
public static DateTime GetPasswordExpirationDate(UserPrincipal user)
{
DirectoryEntry deUser = (DirectoryEntry)user.GetUnderlyingObject();
ActiveDs.IADsUser nativeDeUser = (ActiveDs.IADsUser)deUser.NativeObject;
return nativeDeUser.PasswordExpirationDate;
}
You'll need to add a reference to the ActiveDS COM library typically found at C:\Windows\System32\activeds.tlb.
I got here from Google search and I found the current answers to be outdated and/or cumbersome (I don't want to import COM dlls, and I would like to avoid complex arithmetics if possible). In addition, it seems that the accepted answer doesn't take into account more granular settings for maxPwdAge that could be in effect.
I found out that AD exposes the calculated property msDS-UserPasswordExpiryTimeComputed which can be used directly, instead of performing complex calculations:
public DateTime? GetPasswordExpirationTime()
{
var path = #"LDAP://yourserver";
// null uses the current user's credentials.
var user = "yourUserNameOrNull";
var password = "yourPasswordOrNull";
var idToSearch = "userNameToCheck";
using(var entry = new DirectoryEntry(path, user, password, AuthenticationTypes.Secure))
using(var ds = GetSearcher(entry, $"(sAMAccountName={idToSearch})"))
{
ds.PropertiesToLoad.Add("msDS-UserPasswordExpiryTimeComputed");
var user = ds.FindOne();
return DateTimePropertyFromLong(user, "msDS-UserPasswordExpiryTimeComputed")
}
}
public static DateTime? DateTimePropertyFromLong(SearchResult sr, string propName)
{
if (!sr.Properties.Contains(propName)) return null;
var value = (long) sr.Properties[propName][0];
return value == long.MaxValue ? (DateTime?)null : DateTime.FromFileTimeUtc(value);
}
The relevant bits are just PropertiesToLoad.Add("msDS-UserPasswordExpiryTimeComputed") and the conversion from the strange long format returned by AD via the DateTime.FromFileTimeUtc method.
Edit
As per #t3chb0t, GetSearcher is a simple helper method, responsible for opening a DirectorySearcher over the DirectoryEntry:
private static DirectorySearcher GetSearcher(DirectoryEntry entry, string filter = null)
{
if (filter == null)
return new DirectorySearcher(entry) {ClientTimeout = TimeSpan.FromSeconds(30)};
return new DirectorySearcher(entry, filter) {ClientTimeout = TimeSpan.FromSeconds(30)};
}

reading messages from fb

I successfully login to facebook but while trying to read the mailbox I got the following error: {"(OAuthException - #298) (#298) Requires extended permission: read_mailbox"}
If I add that scope in the URL;
var destinationUrl =
String.Format(
"https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&display=popup&redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token",
AppID, //client_id
"user_posts" //scope
);
and try to get mails:
private void FaceBookScrapper()
{
var client = new FacebookClient(_fbToken);
var input = new List<FbMesseage>();
if (client != null)
{
dynamic result = client.Get("me/inbox", null);
foreach (var item in result.inbox.data)
{
if (item.unread > 0 || item.unseen > 0)
{
foreach (var message in item.comments.data)
{
input.Add(new FbMesseage
{
Id = message.id,
FromName = message.from.name,
FromId = message.from.id,
Text = message.message,
CreatedDate = message.created_time
});
}
FbMesseageCollectionViewModelIns.LoadData(input);
}
}
}
}
}
}
That permission doesn't exist any more - it has been removed, together with the /user/inbox endpoint.
https://developers.facebook.com/docs/apps/changelog#v2_4_deprecations mentions this, and https://developers.facebook.com/docs/graph-api/reference/v2.5/user/inbox as well.
Under the latter URL, it says it right on the very top of the page:
This document refers to a feature that was removed after Graph API v2.4.
There is no way any more to access a user's inbox via API.

Forget password form in asp.net mvc 4

I try to implement forget password form in my asp.net mvc 4 project, everything works fine, but when I try to login to system with new password it told me that I have wrong password.
[HttpPost]
public ActionResult ForgetPassword(UserViewModel userModel) {
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
string enMessage = "Your new password: " + result;
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
_mailHelper.SendEmail(userModel.Email, "New password", enMessage);
}
return RedirectToAction("ConfirmPasswordChange", "Account");
}
Login form:
[HttpPost]
public ActionResult Login(UserViewModel user) {
var users = _userRepo.GetAllEntitiesWithParam("JobsDb_Users_GetByEmail", user.Email).FirstOrDefault();
...
try {
var tryLogin = WebSecurity.Login(users.Username, user.Password, true);
if (tryLogin == WebSecurity.MembershipLoginStatus.Failure)
{
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
ViewBag.Error = "Your password is incorrect.";
new SeoHelper().ReturnSeoTags(this, "Login");
}
return View(user);
}
...
} catch {
...
}
}
inside WebSecurity
public static MembershipLoginStatus Login(string username, string password, bool rememberMe) {
if (Membership.ValidateUser(username, password)) {
FormsAuthentication.SetAuthCookie(username, rememberMe);
return MembershipLoginStatus.Success;
} else {
return MembershipLoginStatus.Failure;
}
}
inside Membership
public override bool ValidateUser(string username, string password) {
if (string.IsNullOrEmpty(username)) {
return false;
}
if (string.IsNullOrEmpty(password)) {
return false;
}
User user = _userRepository.GetAll().FirstOrDefault(usr => usr.Username == username);
if (user == null) {
return false;
}
if (!user.IsApproved.Value) {
return false;
}
if (user.IsLockedOut.Value) {
return false;
}
String hashedPassword = user.Password;
Boolean verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
if (verificationSucceeded) { //here is I have false if try to login using password from forget form
user.PasswordFailuresSinceLastSuccess = 0;
user.LastLoginDate = DateTime.UtcNow;
user.LastActivityDate = DateTime.UtcNow;
} else {
int failures = user.PasswordFailuresSinceLastSuccess.Value;
if (failures < MaxInvalidPasswordAttempts) {
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
} else if (failures >= MaxInvalidPasswordAttempts) {
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.IsLockedOut = true;
}
}
_userRepository.SaveChanges();
if (verificationSucceeded) {
return true;
}
return false;
}
First step is to open up your database and verify that the new password was actually persisted. If it has, the most likely cause is that your repository is working with stale (cached) data.
If you're using Entity Framework, this happens because the framework will, by default, cache the state of the database at the time the DbContext is created, so it is retaining your original password. You can verify this by logging in with the original password.
I am not sure but following code does not look right to me:
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
You fetched the user from repository, make changes to user object in memory and then called SaveChanges() on the repository. Does that work in your world? How does _userRepo.SaveChanges(); knows which object has changed. Do you see correct hashed value in DB after the call? What value you see in ValidateUser() method for password? Is the hashing algorithm consistent both while generating hashed password and while verifying?
I could be wrong, if that's the case it will be good if you share little bit more of analysis around the question I asked above.

Get username in web app in Dynamics 2011 (in C#)

I'm trying to get the username of the current user in a web app that's running inside MS Dynamics 2011.
If I used Environment.UserName it returns the username of the AppPool the app is running under. How do I determine the actual user who is logged in to Dynamics?
Assuming that this is a website that is using windows authentication, this is how you can lookup the username of the request:
var name = Request.RequestContext.HttpContext.User.Identity.Name;
You can then use that name to lookup the SystemUserId of the user and do impersonation if need be.
Guid userGuid;
if(Request.LogonUserIdentity.IsAuthenticated == true)
{
WhoAmIRequest userRequest = new Microsoft.Crm.SdkTypeProxy.WhoAmIRequest();
WhoAmIResponse user = (Microsoft.Crm.SdkTypeProxy.WhoAmIResponse)objCrmService.Execute(userRequest);
userGuid = user.UserId;
}
else //ifd
{
userGuid = new Guid(Context.User.Identity.Name);
}
//Populating a dropdown with all users and selecting the current user
SelectUser(userGuid);
private void SelectUser(Guid userId)
{
BusinessEntityCollection users = LoadUsers();//Load all users
for (int i = 0; i < users.BusinessEntities.Count; i++)
{
DynamicEntity entity = (DynamicEntity)users.BusinessEntities[i];
if (entity.Properties.Contains(“systemuserid”) && ((Key)entity.Properties["systemuserid"]).Value == userId)
{
DDLUsers.Items.Add(new ListItem(entity.Properties["fullname"].ToString(), ((Key)entity.Properties["systemuserid"]).Value.ToString()));
DDLUsers.Items[i].Selected = true;
}
else
{
DDLUsers.Items.Add(new ListItem(entity.Properties["fullname"].ToString(), ((Key)entity.Properties["systemuserid"]).Value.ToString()));
}
}
}

Categories

Resources