In a ASP.net WebForms project, we currently use Forms Authentication, but the client wishes to use Windows Authentication instead. So I've changed the web.config to use Windows authentication. However, the application needs some user input and put in into a session before any webpage can be accessed. We currently do this in the postback of the loginpage.
Since Windows authentication does not have a 'Login' page, how can this be achieved? Should I check on every page it's On_Init event if the session has been set correctly..?
If you need a specific data in session available in every single page, the easiest approach would be to have a dedicated module that checks the condition in one of early pipeline events where the session is available (the acquire request state event sounds most suitable).
public class CustomConditionCheckModule : IHttpModule
{
public void Init( HttpApplication context )
{
context.AcquireRequestState += new EventHandler( acq_req_state );
}
public void acq_req_state( object sender, EventArgs e )
{
// check your condition there - the data is in session
var session = HttpContext.Current.Session;
if ( ... the condition ... )
Response.Redirect( "~/anonymous.page.aspx" );
}
}
Then you also need a page that can be accessed anonymously (you need a section in the web.config for this):
<location path="anonymous.page.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
I think you could go with LDAP (Active Directory Authentication)
with windows authentication in web.config but if its intranet web application or another way i.e. role based security with windows authentication.
Related
I have made an asp.net application. This application has session variables which shows that a user is logged in or logged out.
If there any way to capture the expiration of session without going to single pages and once this is logged out user can be redirected to login( Re-login) page?
Can my asp.net classes inherit some base class which can have some abstract method to check if session is existing or not.
Please suggest me some architecture to do this.
Thanks in advance.
This application has session variables which shows that a user is logged in or logged out.
This can be achieved by checking the HttpContext.Current.Request.IsAuthenticated property.
If there any way to capture the expiration of session without going to single pages and once > this is logged out user can be redirected to login( Re-login) page?
Configure the following elements in your applications web.config to restrict\allow access to resources\pages\directories on your site:
<authorization>
<allow .../>
<deny .../>
</authorization>
http://msdn.microsoft.com/en-us/library/8d82143t
And, configure the FormsAuthentication defaulturl and loginurl attributes to redirect users away from restricted resources.
You can use global.asax's session end event:
void Session_End(Object sender, EventArgs E) {
// your code....
}
When the session expire this event called.
I am using forms authentication with ASP.NET MVC. Within web.config at application level I can set the paths that I require authentication to as follows;
<location path="subdir1">
<system.web>
<authorization>
<allow users ="?" />
</authorization>
</system.web>
</location>
subdir1 is folder name within the Views folder. This works for the web page routing as siteurl.com/subdir1.
However, if my subdir1 is under another dynamically created route, this setting does not work. For instance; siteurl.com/dynamic/subdir1 does not request authentication. dynamic is created at runtime and web.config does not know about it at application start but it should not care about it, I just want it to ask for authentication whenever there is an access to subdir1 route.
Is there any way that I can set the location's path attribute for this case? or do you have any other way to solve this issue?
Any help would be appreciated.
cas sakal
You can control authorization by using the Authorize attribute on the appropriate actions or controllers.
[Authorize]
public ActionResult MyAction()
{
//stuff
}
Some more information can be found at ASP.NET MVC Authorization
You should be using the AuthorizeAttribute on your controllers/actions rather than setting up access in the web.config file for routes that map onto your controllers. You only need to apply the attribute to those actions (methods) that require authorization if not all of your actions require a logged in user.
[Authorize]
public class ProtectedController : Controller
{
// all actions in this controller require the user to be logged in
}
public class MixedController : Controller
{
[Authorize]
public ActionResult ProtectedAction()
{
// this action requires the user to be logged in
}
public ActionResult PublicAction()
{
// this action is available to anonymous users
}
}
I am trying to use Role based authorization in declarative way, when unauthorized user attempt to access a page, it never fire an exception or show the user an error message. What I should do to show unauthorized message? is that possible in declarative way?
using coding is not a nice option sense I have several roles, and folder authorized for several roles while other folders are authorized for one role.
thanks
Use the following code in your Login page to redirect the user to either an unauthorized page or the default page.
protected void Page_Load( object sender, EventArgs e )
{
if( Page.IsPostBack )
return;
if( !Request.IsAuthenticated )
return;
if( !string.IsNullOrEmpty( Request.QueryString["ReturnUrl"] ) && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(Request.QueryString["ReturnUrl"], User,"GET"))
{
// In Forms Authentication, authenticated but unauthorized requests are converted into a Redirect to the Login page.
// Redirect these to an error page instead.
Response.Redirect( "~/UnauthorizedAccess.aspx", false );
}
else
{
Response.Redirect( FormsAuthentication.DefaultUrl, false );
}
}
See this link for a picture of what's happening and more info:
http://www.asp.net/security/tutorials/user-based-authorization-cs
If it fails authorization it will throw an exception. It must be passing. What are you using for authentication? Have you disabled anonymous access?
Perhaps you could make use of a site map. More on those here, plus a bit about tying security to them here.
It's also possible to use web.config to set up permissions for various folders or files. Each folder could have a list of allows or denys like so:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="Administrators" />
<allow roles="Random Role" />
<deny users="*" />
<deny users="?" />
</authorization>
</system.web>
</configuration>
Then when someone hits the page that requires authorization that they don't have permission for it will redirect them to your login page. You could then check the query string for the page they came from and perhaps set up case specific responses, or at the very least if it has a returnURL page on it, say "You are not authorized to see this page."
I have a simple problem which is giving me headaches for a couple of days.
I've created very simple application with login control. I keep user data in web.config file:
<authentication mode="Forms">
<forms name=".RzeskoLoginCookie">
<credentials passwordFormat="Clear">
<user name="test" password="test"/>
</credentials>
</forms>
</authentication>
I will deploy this simple website to IIS on computer on which I do not want to use SQL Server.
My login button event looks like this:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Now the problem:
When I am running a website on VS2008 built in webserver, everything works fine (I can log in). When I copy my website to IIS I am constantly getting this annoying error (after I click Login button):
Failed to generate a user instance of
SQL Server due to failure in
retrieving the user's local
application data path. Please make
sure the user has a local user profile
on the computer. The connection will
be closed.
I also observed that in my App_Data folder some weird files are being created.
To sum up. What I want to achieve is to use user credentials from web.config file, without using sql server.
I'd appreciate any help
Kind Regards
PK
From the MSDN page for Login control:
*
The Login control uses a membership
provider to obtain user credentials.
Unless you specify otherwise, the
Login control uses the default
membership provider defined in the
Web.config file. To specify a
different provider, set the
MembershipProvider property to one of
the membership provider names defined
in your application's Web.config file.
For more information, see Membership
Providers.
*
The default Membership provider is the AspNetSqlProvider which uses a SQL Server database as its user store.
If you want to provide a custom authentication routine, you can either write your own custom Membership provider or handle the OnAuthenticate method of the Login control to provide your own authentication logic.
If you notice in your code, you have the method declaration for handling the <asp:Login> control's LoggingIn event:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
This control interfaces with the ASP.NET Membership provider which is probably why it is looking for a connection string.
So rather than using the <asp:Login> control, simply use a button and handle the Click event so that there is no use of Membership:
<asp:Button id="LoginButton" Text="Login" OnClick="Login_OnClick" runat="server" />
Code behind (notice the different signature of the method):
public void Login_OnClick(object sender, EventArgs args)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Ok, thanks everybody for pointing out the solution.
I finally managed to avoid that error by creating my own authentication event (associated with the login control).
I'm playing around with authentication and authorization to prepare for some task. I've created two pages: Login.aspx and Default.aspx. In config file i've set authentication to forms and denied unauthenticated users access:
<authentication mode="Forms">
<forms name="aaa" defaultUrl="~/Login.aspx" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Then I've written some simple code to authenticate my user in Login.aspx:
protected void Page_Load(object sender, EventArgs e)
{
GenericIdentity identity = new GenericIdentity("aga", "bbb");
Context.User = new GenericPrincipal(identity, new String[] { "User" }); ;
Response.Redirect("~/Default.aspx");
}
When i run it, the redirection doesn't take place. Instead Login.aspx is called over and over because the user is not authenticated (Context.User.Identity.IsAuthenticated is false at every load). What am i doing wrong?
Context.User only sets the principal for the current request. Once the redirect takes place, the current request ends and a new one begins with the non-overridden principal again (which is apparently not authenticated). So, setting Context.User doesn't actually authenticate anything.
Using FormsAuthentication.SetAuthCookie() will set the user's cookie to a valid value accepted by the FormsAuthentication provider, or put the token in the URL. You can redirect to your heart's content because the cookie obviously sticks with the user for future requests.
From MSDN (em added):
With forms authentication, you can use the SetAuthCookie method when you want to authenticate a user but still retain control of the navigation with redirects.
As stated, this does not necessarily require cookies - the name is a little misleading, because it will still work via the URL if FormsAuthentication is in cookieless mode:
The SetAuthCookie method adds a forms-authentication ticket to either the cookies collection, or to the URL if CookiesSupported is false.
Use FormsAuthentication.SetAuthCookie(..). Or FormsAuthentication.RedirectFromLoginPage(..).
You need to actually set the user as authenticated. All of the following methods will work and let you actually get away from your login screen.
FormsAuthentication.Authenticate()
FormsAuthentication.RedirectFromLoginPage()
FormsAuthentication.SetAuthCookie()
Lots of ways to get to the same result.
You need to actually make a call to the formsAuthentication provider to set the login.
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, chkPersistLogin.Checked)
is a simple example
After creating the dummy Context.User, you need to perform a FormsAuthentication.SetAuthCookie or RedirectFromLoginPage method.