Owin challenge triggers in the second intent on DNN - forms-authentication

I've created a custom login module for DNN with mixing authentications: 1) Authenticate thru ADFS. 2) Authenticate with regular forms authentication. Everything is working except:
protected void Adfs_Click(object sender, EventArgs e)
{
HttpContext.Current.GetOwinContext()
.Authentication.Challenge(new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
the first click reloads the page and always works the second time. I've tried to disable the forms authentications like this post suggest, but because I'm working with DNN I can't do that.
I also test triggering the event on the Page_Load and works, but I want to allow the DNN native users to be able to login direct to DNN (host user) ... so I can't do the challenge there either.
Any help on what should I do to make the challenge works with the first click?
Thanks in advance.

Related

ASP.NET cannot automatically authenticate user

I have ASP.NET app which can automatically login anyone who is in my database. Any page is auto redirected to login page if user is not authenticated and login page will find user and authenticate him.
protected void Page_Load(object sender, EventArgs e) {
var emp = SQLSelects.SQLSelects.SelectEmployee(Request.LogonUserIdentity.Name);
if (emp != null){
Session.Add("UserName", emp.Login);
Session.Add("Access", (int)emp.acessLevel);
FormsAuthentication.RedirectFromLoginPage(emp.Login, true);
}
}
Everything worked but now it just throw some kind of Login pop-up formular and request login and password. I don't know why, because I do not know that I was coding anything like that. Any combination of user name and password is not working
In Local Host everything work like it should so I cannot find any problem, nothing. In remote server there is just white screen and login form.
Long story short, windows server itself turn off authentication of everything (all our websites fall) and equest update. After update everything is OK.

How to know when login is successful working with the asp.net web application template

I created a new asp.net web application using the template that visual studio has. That type of project create a login out-of-the-box which I configured with the aspnet_regsql command to work with my database.
Now, when someone logs into the application, I need to know whether or not the login was sucessful, so I can save in Session[''] the user name among other things.
I was expecting to find a method that returns true or false but instead in the Login.aspx.cs is just the Page_Load method and I don't understand how it works.
I tried associated a onclick method that get the value of the UserName control, but obviously, that only works when the user log in for the first time, if the user check "Remember me next time" it won't work.
The AuthenticateRequest event is raised when the user has been authenticated, however in this event you do not have access to the SessionState yet. Therefore, to save the Session you should consider the PostAcquireRequestState application event.
ASP.NET Application Life Cycle Overview for IIS 7.0
ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0
For additional info:
AuthenticateRequest event
Example:
In global.asax
void Application_PostAcquireRequestState(object sender, EventArgs e)
{
if (Context.Session != null)
{
Application.Lock();
Session["user"] = User.Identity.Name;
Application.UnLock();
}
}
Additionally, if you are using the LoginControl, you can handle the LoggedIn event:
ASPX
<asp:Login runat="server" ID="login" DestinationPageUrl="~/Default.aspx"
FailureAction="RedirectToLoginPage"
onloggedin="login_LoggedIn" ...>
....
ASPX code behind
protected void login_LoggedIn(object sender, EventArgs e)
{
// set the Session here
}
The aspx web project template makes use of the asp:Login control, which does the authentication for you.
If you need to customize the login, you can roll your own username / password inputs, and then call the membership API directly, e.g.
if (Membership.ValidateUser(username, password))
{
FormsAuthentication.SetAuthCookie(username, rememberMe);
// Do your custom stuff here
...
You can also check to see whether the user is authenticated by using
UserPrincipal.Identity.IsAuthenticated
See MSDN for more details

Control ASP.NET Return from Login

I've got a requirement such that, when a user logs in while completing a multi-form data submission process, their profile is checked against the data they've already submitted and certain classes of users will be shown an alert message; i.e. some users get a popup message when they login.
The popup will use the ModalPopupExtender from the Ajax toolkit which is in line with similar functionality elsewhere in the code base.
The problem I've got is that as soon as the user is validated, the user is always redirected to the originating page; I want to suspend this action until the user has been shown the message and then perform the redirection when the user clicks to dismiss the message.
Can anyone suggest a solution to this (using .NET 3.5)?
EDIT
Since it's been asked for, the login page has a user control which contains an control. The control handles the OnAuthenticate event which basically calls:
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
bool isValidUser = Membership.ValidateUser(FullLogin.UserName, FullLogin.Password);
if (isValidUser)
{
e.Authenticated = true;
}
...
}
It also handles the LoggedIn event which performs some business logic and raises a 'LogInSuccessful' or 'LoginFailed' event handled by the page. A successful login will the redirect the user back to the originating page.
I've already refactored out the manual redirection code to be called when the info box is dismissed but it appears that forms authentication is redirecting the user automatically which is the behaviour I'm trying to override.
When you login with forms authentication, user is carried to the login form and back to the origination page by asp.net.
Once you have authenticated the user, it will take him back to the originating page.
If you have to do it on this page, you must for this group of users, cancel the authenticate and then show the message.
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
bool isValidUser = Membership.ValidateUser(FullLogin.UserName, FullLogin.Password);
Session["isValidUser"] = isValidUser;
if (!Session.ContainsKey("isValidUser"))
{
e.Authenticated = false;
}
else
{
e.Authenticated = (bool)Session["isValidUser"];
}
...
}
When the user clicks the ok button, you must then postback and authenticate the user. This will need you to store the result of authenticate from the previous call in session.
It might be simpler to put this message in a common master page, let asp take the user back to the originating page and show the message there.

Forms authentication - logging out and page history

In my ASP.NET site, when a user clicks logout, I call FormsAuthentication.SignOut and Session.Abandon and redirect them to the login page. This works fine.
However, when I click "back" in the browser I can still see the last page viewed before logout was clicked. When I click on anything I am returned to the logon page as expected.
Is there anyway to expire the page that logout was clicked on so that users never see it when they click back?
Prevent credential and content caching:
First, ensure the forms cookie is not being created sticky:
FormsAuthentication.SetAuthCookie(userName, false);
Next, a little something in the Global.asax to prevent page requests from caching:
public override void Init()
{
base.Init();
BeginRequest += new EventHandler(OnBeginRequest);
}
void OnBeginRequest(object sender, EventArgs e)
{
if (!(Request.Path.EndsWith("Resource.axd")))
{
Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
}
}
The combination of the above two approaches has fixed a similar issue in a few apps I've worked on. We intentionally allowed .axd file caching to keep performance impact as minimal as possible - we have heavy use of third party controls that generate axd requests in the background.

Protect some pages from direct access in ASP.NET

I have an ASP.NET page called admin.aspx that needs to be protected from direct access.
I want it to be accessed only when the user enter his name & password in another page called login.aspx.
I'm working in ASP.NET with Visual Basic .NET 2008, and I have no idea how to do it.
How can I do it?
The correct term for this behavior is Authorization
Some things I need to know beforehand:
Do you have your own Login / Logout Logic?
Are you using a custom User database / table?
If both of the above were answered with a yes: Have you read / heard something about Membership- and RoleProviders?
.NET has great built in mechanisms for solving this problem. It doesn't just offer great configuration possibilities, it is also very easy to implement!
Here is a very very detailed walk trough on the ASP.NET Membership Provider:
ASP.NET 2.0 Membership and Roles Tutorial Series
Even though it is using ASP.NET 2.0 and C#, it shouldn't really be that different on .NET3.5/4.0 and VB.NET
I found it :
In the login page ("login.aspx") do this :
Session("Name") = "Yes"
Response.Redirect("admin.aspx")
In the admin page ("admin.aspx") this :
If Session("Name") = "Yes" Then
'You can here display anything you want, or just leave it blank
Else
Response.Redirect("ErrorPage.aspx")
End If
You should check the user session first before loading your page:
protected void Page_Load(object sender, EventArgs e)
{
if (session == null)
{
// Just redirect to login page or no access page warning.**
}
if (!Page.IsPostBack)
{
//If your were logged in then you will access this page
}
}
You can handle it via Forms authentication. In your case you want to make sure that you restrict the access of admin.aspx so you can do so by giving that entry in web .config by specifying the location tag. Check out this site:
http://www.dnzone.com/go?60
HTH

Resources