Every time I try to Response.Redirect("tothepageIwant.aspx"); tt takes me to ~/Account/Logon.aspx
Why is this happening? I'm using Forms Authentication, with a custom method of authenticating, using PrincipalContext.ValidateCredentials.
If the credentials are valid, I want to Redirect.Response to the page I'm allowing the user to reach.
Instead, anytime I successfully login, it redirects me to the old Account/Logon.aspx.
Any suggestions? Anything I need to look out for when using Forms Authentication with custom method of authenticating?
EDIT (add code):
protected void Submit1_Click(object sender, EventArgs e)
{
var auth = new AuthClass();
var result = auth.ValidateCredentials(UserEmail.Text, UserPass.Text);
if (result)
{
Response.Redirect("~/Members/RollReport.aspx");
}
else
{
Msg.Text = "Not authorized to access this page.";
}
}
public bool ValidateCredentials(string user, string pass)
{
using (var pc = new PrincipalContext(ContextType.Domain, "Domain.name"))
{
// validate the credentials
try
{
var isValid = pc.ValidateCredentials(user, pass);
if (isValid)
{
var isAuth = AuthorizeUser(user);
return isAuth;
}
else
{
return false;
}
}
catch (ActiveDirectoryOperationException)
{
throw;
}
}
}
private bool AuthorizeUser(string user)
{
var isAuth = false;
var authList = (List<string>)HttpContext.Current.Cache["AuthList"];
foreach (var id in authList)
{
if (id == user)
{
isAuth = true;
}
}
return isAuth;
}
var userName = Request.ServerVariables["LOGON_USER"];//or some other method of capturing the value from the username
var pc = new PrincipalContext(ContextType.Domain);
var userFind = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, userName);
if(userFind != null)
{
HttpContext.Current.Session["username"] = userFind.DisplayName;
}
If you want to check and redirect.. store the value inside a session variable inside the Global.asax
protected void Session_Start(object sender, EventArgs e)
{
//declare and Initialize your LogIn Session variable
HttpContext.Current.Session["username"] = string.Empty;
}
On the Page_Load of your login page assign the value if the code above succeeds
if(HttpContext.Current.Session["username"] == null)
{
//Force them to redirect to the login page
}
else
{
Response.Redirect("tothepageIwant.aspx");
}
if you want to do the same thing inside a using(){} statement
string fullName = null;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(context,"yourusernamehere")) //User.Identity.Name
{
if (user != null)
{
fullName = user.DisplayName;
}
}
}
use the debugger and inspect all of the user. Properties ok
Related
In my Xamarin.Forms project I have a login form that logs in the user and then redirects them to another page. I want to show an ActivityIndicator while it attempts to login, but setting IsVisible to true doesn't actually take effect before the login function is done. My code looks like this:
void OnLoginButtonClicked(object sender, EventArgs e)
{
LoadingIndicator.IsVisible = true;
Login();
}
public void Login()
{
var user = new User
{
Email = usernameEntry.Text,
Password = passwordEntry.Text
};
User validUser = AreCredentialsCorrect(user);
if (validUser != null)
{
Navigation.PushAsync(new ProfilePage());
}
else
{
messageLabel.Text = "Login failed";
passwordEntry.Text = string.Empty;
//It will only show the LoadingIndicator at this point.
}
}
If the user is correct, it never shows the LoadingIndicator because it navigates to another page before it can show it.
If the user is invalid, it will only show the LoadingIndicator after it hits the else clause and shows the "Login failed". Can anyone figure why that is, and what I can do to fix it?
Use Async calls and await the main block of operations. If anything you want to update/change in UI, do it using BeginInvokeOnMainThread.
void OnLoginButtonClicked(object sender, EventArgs e)
{
LoadingIndicator.IsVisible = true;
await Login();
}
public async void Login()
{
await Task.Run(() => {
var user = new User
{
Email = usernameEntry.Text,
Password = passwordEntry.Text
};
User validUser = AreCredentialsCorrect(user);
}).ContinueWith((a) => SomeMethod(validUser));
}
public void SomeMethod()
{
Device.BeginInvokeOnMainThread(() =>
if (validUser != null)
{
Navigation.PushAsync(new ProfilePage());
}
else
{
messageLabel.Text = "Login failed";
passwordEntry.Text = string.Empty;
//It will only show the LoadingIndicator at this point.
}
}
}
Try using async/await. Allow the UI to update while also navigating.
async void OnLoginButtonClicked(object sender, EventArgs e)
{
LoadingIndicator.IsVisible = true;
await Login();
}
public async Task Login()
{
var user = new User
{
Email = usernameEntry.Text,
Password = passwordEntry.Text
};
User validUser = AreCredentialsCorrect(user);
if (validUser != null)
{
await Navigation.PushAsync(new ProfilePage());
}
else
{
messageLabel.Text = "Login failed";
passwordEntry.Text = string.Empty;
//It will only show the LoadingIndicator at this point.
}
}
Two possible explanations here one it could be redirecting so fast that it doesn't have time to display the loadingindicator, I have experienced this problem before. We had a really nice loading symbol and animation but then we switched to Aurelia framework and it logs in so fast it just doesn't have time to display it even though it was actually working. As for code changes I would try to add it into the login function as well at least for right now to give some clarity to if its actually just logging in so fast its not displayed or its just not displaying at all. Her is my suggestion.
void OnLoginButtonClicked(object sender, EventArgs e)
{
LoadingIndicator.IsVisible = true;
Login(LoadingIndicator.IsVisible);
}
public void Login(Bool IsVisible)<--- might have type wrong not familiar with you custom defines types I would expect it to be a bool though.
IsVisible = true;
{
var user = new User
{
IsVisible = true;
Email = usernameEntry.Text,
Password = passwordEntry.Text
};
User validUser = AreCredentialsCorrect(user);
if (validUser != null)
{
IsVisible = true;
Navigation.PushAsync(new ProfilePage());
}
else
{
IsVisible = true;
messageLabel.Text = "Login failed";
passwordEntry.Text = string.Empty;
//It will only show the LoadingIndicator at this point.
}
}
If nothing else this might help clarify why it isn't being displayed. Also don't forget to use the web debugger f12 by default on most browsers and look for the element that will contain the Indicator.
Hope this helps! If not let me know and I'll remove the answer(I had to use an answer because I can't comment under 50 rep) Cheers!
I am trying to track my login attempts but its only ever staying at one I need keep a running track of failed login attempts probably something simple wrong with my execution here.
public int validateUser(string username, string userPassword)
{
var _currentUser = _db.users.FirstOrDefault(a => a.username == username);
int _loginAttempts = =0;
if (_currentUser != null)
{
if (isEncryptionEnabled == true)
{
string descriptedPassword = encrypt.DecryptRijndael(_currentUser.password, _currentUser.salt.ToString());
if (descriptedPassword == userPassword)
return 0;
else
_loginAttempts++;
}
else
{
var _unecryptedUser = _db.users.FirstOrDefault(a => a.username == username && a.password == userPassword);
if (_unecryptedUser != null)
return 0;//zero represents sufcessfull login attempts
return _loginAttempts++; // if anything greater zero is a failed login attempt send it back.
}
}
return _loginAttempts;
}
This is how the function is being called a button click of Login.aspx this is a webforms application.
protected void btnLogin_Click(object sender, EventArgs e)
{
DBContext _db = new DBContext();
int canILogin = _db.validateUser(txtUsername.Text, txtPassword.Text);
if (canILogin == 0)// if i can loging after checking the encripted password then lets go to default page
Response.Redirect("default.aspx");
else
Response.Redirect("login.aspx?attempt=" + canILogin.ToString());
if (Convert.ToInt16(Request.QueryString["attempt"]) > 0)
{
lblFailed.Text = "Failed Login Attempts"+ canILogin.ToString();
lblFailed.Visible = true;
}
}
grovesNL is correct. Move your declaration for_loginAttempts outside the method. Try declaring it in the parent class. Like this:
class DBContext
{
private int _loginAttempts = 0; // I assume private to keep from exposing it for security
public int validateUser(string username, string userPassword)
{
// some code to test userPassword and increase or reset counter as needed
}
// more methods etc.
}
I am receiving the classic, Object reference not set to an instance of an object in my project when viewing the hosted website. Works when building a debug version locally.
Live
Example of code that is showing error message:
using System.DirectoryServices.AccountManagement;
protected void Page_Load(object sender, EventArgs e)
{
try
{
String username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
username = username.Substring(3);
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "dc");
UserPrincipal user = UserPrincipal.FindByIdentity(pc, username);
string NTDisplayName = user.DisplayName;
//String NTUser = user.SamAccountName;
lblntuser.Text = NTDisplayName;
}
catch (Exception Ex)
{
lblntuser.Text = Ex.Message;
System.Diagnostics.Debug.Write(Ex.Message);
}
}
Try this:
protected void Page_Load(object sender, EventArgs e)
{
try
{
// you need to also take into account that someone could get to your
// page without having a Windows account.... check for NULL !
if (System.Security.Principal.WindowsIdentity == null ||
System.Security.Principal.WindowsIdentity.GetCurrent() == null)
{
return; // possibly return a message or something....
}
String username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
// if the user name returned is null or empty -> abort
if(string.IsNullOrEmpty(username))
{
return;
}
username = username.Substring(3);
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "dc");
UserPrincipal user = UserPrincipal.FindByIdentity(pc, username);
// finding the user of course can also fail - check for NULL !!
if (user != null)
{
string NTDisplayName = user.DisplayName;
//String NTUser = user.SamAccountName;
lblntuser.Text = NTDisplayName;
}
}
catch (Exception Ex)
{
lblntuser.Text = Ex.Message;
System.Diagnostics.Debug.Write(Ex.Message);
}
}
I'm trying to implement a Google OpenID login
I have the following questions:
Where can I get the value of the variable openidurl in the line
IAuthenticationRequest request = openid.CreateRequest(openidurl);
2.. How can I restrict the login for a certain Google Apps Domain only?
The code is the following:
protected void Page_Load(object sender, EventArgs e)
{
OpenIdRelyingParty openid = new OpenIdRelyingParty();
var response = openid.GetResponse();
if (response != null)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
var fetch = response.GetExtension<FetchResponse>();
string email = string.Empty;
if (fetch != null)
{
email = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
}
//FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false);
Session["email"] = email;
Response.Redirect("profile.aspx");
break;
}
}
}
protected void OpenLogin_Click(object src, CommandEventArgs e)
{
string openidurl = "https://www.google.com/accounts/o8/id?id=initial_id"; //auxiliary initial id. ??????
//The Request
using (OpenIdRelyingParty openid = new OpenIdRelyingParty())
{
IAuthenticationRequest request = openid.CreateRequest(openidurl);
var fetch = new FetchRequest();
fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
request.AddExtension(fetch);
// Send your visitor to their Provider for authentication.
request.RedirectToProvider();
}
}
}
Thanks in advance, this is the first time I use Google OpenIDs.
I have the following code:
protected void Page_Load(object sender, EventArgs e)
{
var openId = new OpenIdRelyingParty();
HttpContext httpContext = HttpContext.Current;
var headers = new WebHeaderCollection();
foreach (string header in httpContext.Request.Headers)
{
headers.Add(header, httpContext.Request.Headers[header]);
}
string requestUrl = string.Format("http://localhost:12345/Login/{0}",
httpContext.Request.Url.Query);
var requestInfo = new HttpRequestInfo(httpContext.Request.HttpMethod,
new Uri(requestUrl),
httpContext.Request.RawUrl, headers,
httpContext.Request.InputStream);
var response = openId.GetResponse(requestInfo);
if (response != null)
{
ClaimsResponse claimResponse = response.GetExtension<ClaimsResponse>();
lblUser.Text = claimResponse.FullName;
if (response.Exception != null)
{
lblError.Text = response.Exception.Message;
}
}
}
protected void btnTest_Click(object sender, EventArgs e)
{
try
{
using (OpenIdRelyingParty openId = new OpenIdRelyingParty())
{
string identifier = #"https://www.google.com/accounts/o8/id";
var request = openId.CreateRequest(identifier,
new Realm("http://localhost:12345/"),
new Uri("http://localhost:12345/Login/"));
request.AddExtension(new ClaimsRequest
{
Email = DemandLevel.Require
});
request.RedirectToProvider();
}
}
catch (Exception ex)
{
// TODO: log exception
throw;
}
}
When I execute the code, user is authenticated but ClaimsResponse is null.
Code works fine with MyOpenId.
Any help would be appreciated.
The information here is useful: Retrieve OpenId User Information (Claims) across providers
The gold nugget you are likely missing in your app is the AXFetchAsSregTransform.