Object reference not set to an instance of an object. - asp.net

My codes below don't have any errors during the compile time but when I open the page an error occur at the Guid currentUserId = (Guid)currentUser.ProviderUserKey; stating that Object reference not set to an instance of an object.
foreach(DataRowView ProfileInfo in UserProfileDataSource.Select(DataSourceSelectArguments.Empty))
{
//Some codes where I display data from database
}
protected void UserProfileDataSource_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
MembershipUser currentUser = Membership.GetUser();
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
e.Command.Parameters["USERID"].Value = currentUserId;
}
and here is my SQLDataSource
<asp:SqlDataSource ID="UserProfileDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
onselecting="UserProfileDataSource_Selecting"
ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>"
SelectCommand="SELECT "TITLE", "FAMILYNAME", "GIVENNAME", "MIDDLENAME", "POSITION", "INSTITUTIONNAME", "USERID", "REGISTEREDDATE" FROM "MEMBERINFO" WHERE ("USERID" = ?)">
<SelectParameters>
<asp:Parameter Name="USERID" Type="Object" />
</SelectParameters>
</asp:SqlDataSource>
Ernie

you should check to make sure that currentUser is not null before trying to access it:
if ( currentUser != null )
{
/* do stuff here */
}
else
{
/* do something else, like show an error message perhaps */
}

try this code:
string username = HttpContext.Current.User.Identity.Name;
if(!string.IsNullOrEmpty(username))
{
MembershipUser currentUser = Membership.GetUser(username);
Guid currentUserId = new Guid(currentUser.ProviderUserKey.ToString());
}

You appear to be allowing anonymous users to access a page that requires a logged in user. You can't get the user if they haven't logged in yet.
Security consists of two parts, authorization and authentication. Authentication is logging in, but authorization is denying access to pages to unauthorized users (such as ones that have not yet logged in, or do not have the correct roles assigned to them).
If your page depends on an authenticated user, then you should deny anonymous users access. If the page does not depend on an authenticated user, but merely makes use of member information if they are authenticated, then you need to guard against calling member functions (or anything that uses member data) if the user is not authenticated.

The issue is Bad code.
Try these steps:-
In your website, set the "Start page" to the correct "login" page.
Once you login, correctly and then land on the page, you should be able to access this property.
You may get into the same error if you click logout button and the landing page might be referring to this membership information.
So the work-around is simple.
1.Set the start page correctly.
2.Handle the 2 cases:- user is logged in and user is not logged in efficiently.
an example is as below:-
protected void Page_Load(object sender, EventArgs e)
{
if (Membership.GetUser() == null)
{ Label1.Text = "";
Label_TotalCoxxxxxxxxx.Text = "";
Label_TotalSuxxxxxxxxx.Text ="";
}
else {
string loggedinuser = Membership.GetUser().ToString();
Label1.Text = loggedinuser;
Label_TotalCoxxxxxxxxx.Text = "Total of xxxxxxxxxx Added in the current Month:-";
Label_TotalSuxxxxxxxxx.Text = "Total of yyyyyyyyyy done in the current Month:-";
}
}

Related

approve user umbraco membership system

hi i am working on Umbraco(6.1.2) membership system
ive made login ,registration, and authentication page
after registeration user is redirected to authentication page with token_id
now i want to set this user approved for this purpose i write the following code
but there is some error check it
string uname = Request.QueryString["a"];
string uguid = Request.QueryString["b"];
MembershipUser thisUser = Membership.GetUser(uname);
if (thisUser != null)
{
if (!thisUser.IsApproved)
{
MemberProfile mp = MemberProfile.GetUserProfile(uname);
if (mp != null)
{
if (mp.AuthGuid == uguid)
{
thisUser.IsApproved = true;
Membership.UpdateUser(thisUser);
lblMessage.Text = "Thank you for confirming your email address";
}
else
{
lblMessage.Text = "Error confirming your email address";
}
}
else
{
lblMessage.Text = "Error confirming your email address";
}
}
else
{
lblMessage.Text = "Email address is already confirmed";
}
}
control is return to else condition from this condition "if (!thisUser.IsApproved)"
and also if i reverse the condition it gets into if block and executes all commands without errors but still not mark user as approved
plz help me
Refrence:Authenticating new members before activating
I had problem with approved as well.
Now I just use this in my code:
MembershipUser user = Membership.GetUser(nodeIdOrUsername);
user.IsApproved = true;
Membership.UpdateUser(user);
You may also need to add a property to your Member type, eg. isApproved and then add it to your provider in web.config in profile > properties section:
<add name="isApproved" allowAnonymous="false" provider="UmbracoMembershipProvider" type="System.Boolean"/>
and then extend ProfileBase and added an Approved property.
In web.config in membership > provider section add this property to your provider key eg.:
<add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" umbracoApprovePropertyTypeAlias="isApproved" umbracoLockPropertyTypeAlias="isLocked" ... />
I can't remember for sure but I think without it it didn't work.
I hope this will be of any use.

ASP.NET Authentication

I have the following a login page where the user enters in their username and password.
With that info, I need to then make sure that they are part of the Admin1 role If so, I like to set a cookie on the user's machine.
With the code I have below User.InRole it doesn't enter into the if statement. If I uncomment the FormsAuthentication.SetAuthCookie(txtUserName.Text, true); above it works.
Meaning shouldn't I set the cookie only if the user is part of Admin1 role
I have the following but does not seem to work:
if (Membership.ValidateUser(txtUserName.Text, txtPassword.Text))
{
// FormsAuthentication.SetAuthCookie(txtUserName.Text, true);
if (User.IsInRole("Admin1"))
{
// code never reaches here
FormsAuthentication.SetAuthCookie(txtUserName.Text, true);
User.IsInRole("Admin1") is false right after validation, because principal object hasn't been attached to the current HttpContext yet.
If you really want to use Context.User, you need to manually attach principal object.
var username = txtUserName.Text;
var password = txtPassword.Text;
if (Membership.ValidateUser(username , password))
{
var roles = Roles.GetRolesForUser(username);
var identity = new GenericIdentity(username);
var principal = new GenericPrincipal(identity, roles);
Context.User = principal;
// Now you can use Context.User
// Basically User.IsInRole("Admin1") is same as roles.Contains("Admin1")
if (User.IsInRole("Admin1"))
{
FormsAuthentication.SetAuthCookie(username, true);
}
}
Updated - Authenticate user using Login Control
Since you are using Membership Provider and Role Provider, I would like to suggest to use Login Control.
Once user is authenticated, you can use LoggedIn event to redirect user to appropiate page.
<asp:Login ID="LoginUser" runat="server" EnableViewState="false"
RenderOuterTable="false" OnLoggedIn="LoginUser_LoggedIn">
...
</asp:Login>
protected void LoginUser_LoggedIn(object sender, EventArgs e)
{
// Now we know that user is authenticated
// Membership user = Membership.GetUser(Login1.Username);
var roles = Roles.GetRolesForUser(Login1.Username);
if(roles.Contains("Admin1"))
Response.Redirect("~/Admin/");
else
Response.Redirect("~/Users/");
}

How can i validate password for user login

I have the following code to check for valid users:
protected void Login_LoginError(object sender, EventArgs e) {
//See if this user exists in the database
MembershipUser userinfo = Membership.GetUser(Login.UserName);
if (userinfo == null || !userinfo.IsApproved || userinfo.IsLockedOut) {
//The user entered an invalid username/password...
Login.FailureText = "Invalid User/Password";
} else {
Login.FailureText = string.Empty;
}
}
This code doesn't show the failure text when the password is wrong for users, I need code-behind logic for validating both the user and password! Any suggestions appreciated.
You should use the Authenticate handler on the login control. For more reading see this link
If you're using the out of the box MembershipProvider you can authenticate your user with the Membership.ValidateUser method in the Authenticate handler.

Custom authentication module inheriting IHttpModule issue

LoginPage.aspx:-
protected void Button1_Click(object sender, EventArgs e)
{
Context.Items["Username"] = txtUserId.Text;
Context.Items["Password"] = txtPassword.Text;
//
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Context.Items["Username"].ToString(), DateTime.Now, DateTime.Now.AddMinutes(10), true, "users", FormsAuthentication.FormsCookiePath);
// Encrypt the cookie using the machine key for secure transport
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, // Name of auth cookie
hash); // Hashed ticket
// Set the cookie's expiration time to the tickets expiration time
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
Response.Cookies.Add(cookie);
Response.Redirect("Default.aspx");
}
Global.asax file:-
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Get the stored user-data, in this case, our roles
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
Response.Write(HttpContext.Current.User.Identity.Name);
Response.Redirect("Default.aspx");
}
}
}
}
I get the following error after signing in
This webpage has a redirect loop.
The webpage at http://localhost:1067/Default.aspx has resulted in too many redirects. Clearing your cookies for this site or allowing third-party cookies may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer.
This is the rough idea of what your module should look like. Your module will run on every request. You don't invoke it or pass anything to it, it just automatically fires whenever a request is made that ASP.Net is set to process.
Your module will do two things, 1) authenticate a user in the login page, 2) authenticate a user on subsequent pages. The first step is to subscribe to the BeginRequest method which will be given the current HttpApplication as the first parameter. From there you need to determine if the user is on your login page or not. If they're not on your login page, check your session or cookie or querystring token, or whatever you're using to make sure that they're still valid. If they're invalid, bounce them back to the login page.
If they're on your login page and have made a POST, look at the raw form fields and validate them. TextBoxes, checkboxes, etc don't exist here, only raw form fields. If they're valid, set your authentication token however you want (session, cookies, etc). If they're invalid, either redirect to the login page or inject a "try again" message or something.
Also, if you double-post a message please reference it so that we can follow the chain of what was already said.
class MyModule : IHttpModule
{
void IHttpModule.Init(HttpApplication context)
{
//Subscribe to the BeginRequest event
context.BeginRequest += new EventHandler(this.Application_BeginRequest);
}
private void Application_BeginRequest(Object source, EventArgs e)
{
//Initialize our variables, null checks should be put here, too
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
System.Web.SessionState.HttpSessionState s = context.Session;
//Normally our module needs to validate every request to make sure our request is still authenticated.
//The exception to that rule is on our logon page where they obviously don't have credentials yet.
if(!context.Request.FilePath.ToLowerInvariant().StartsWith("/login.aspx")){
//If we're here then we're not on the logon page, validate our current session according to whatever logic we want
if (s != null && s["isvalid"] == "true"){
return;
}else{
context.Response.Redirect("/login.aspx");
}
}else{
//If we're here then we're on the login page itself. If there's a post, assume that they've hit the login button
if (context.Request.HttpMethod == "POST")
{
//Whatever your form variables are called
string username = context.Request.Form["username"];
string password = context.Request.Form["password"];
//Your own validation logic would go here
if (MyCustomLogin.IsUserValid(username, password))
{
s["isvalid"] = "true";
context.Response.Redirect("/Home.aspx");
}else{
s["isvalid"] = "false";
context.Response.Redirect("/login.aspx?error=invalid_login");
}
}else{
//If we're here then the request is probably a GET or HEAD which would be from a person
//initially browsing to our page so just do nothing and pass it through normally
}
}
}
}
There is no direct way to have access to this information in the module (for authenticated user, you can access the username via the context, but not the password). The module checks if a request is carrying required authentication information and serve or deny the request based on that. Unless you deliberately from the login page collect this information and store somewhere where you can access it in the module, e.g session. But ideally, storing password is not widely recommended, collect it use it for authentication and destroy.
You might ideally throw more light on the reason why you want to have access to this information in the module and guys can then suggest methods to accomplish it.
Edited, after Chandan comment:
#Chandan, your comment here suggest to me what you want to do is use httpmodule for your authentication as against using standard form authentication. If I am on track, then you can check this project on codeproject at http://www.codeproject.com/KB/web-security/AspNetCustomAuth.aspx. Goodluck

Page.Profile not saving after user created in a CreateUserWizard

I Have the following code which fires OnCreatedUser and doesn't throw any errors. Profile.Title is getting set to the correct value when inspected after the assignment.
public void CreateUserForm_CreatedUser(object sender, EventArgs e)
{
var ddlTitle = (DropDownList)CreateUserWizardStep1.ContentTemplateContainer.FindControl("Title");
Profile.Title = ddlTitle.SelectedValue;
Profile.Save();
}
However, when I test Profile.Title on subsequent pages (the user is definitely logged in) it is == "";
I'm guessing that this is the users old anonymous profile, not the new profile associated with their newly registered user account.
I've tried adding a Profile_MigrateAnonymous method (as suggested here) to my Global.asax but this code doesn't get hit.
How do I save title to the new users account profile?
UPDATE
Here's the code
public void CreateUserForm_CreatedUser(object sender, EventArgs e)
{
var ddlTitle = (DropDownList)CreateUserWizardStep1.ContentTemplateContainer.FindControl("Title");
var emailTextBox = (TextBox)CreateUserWizardStep1.ContentTemplateContainer.FindControl("UserName");
UserProfile profile = (UserProfile)ProfileBase.Create(emailTextBox.Text.Trim());
profile.Title = ddlTitle.SelectedValue;
profile.Save();
}
I think you're correct that the user is still anonymous while that method is called. I'm not familiar with Profile, but I think you need to look the profile up by username instead of relying on the current profile.

Resources