Configuring multiple welcome pages in Seam - seam

I have a Seam application where the Login page is the default welcome page when the application is accessed. I have a few other pages for eg. Change password or Reset Password which donot require any authentication when they are accessed, as the user will fill in their details on those pages. But I cannot access these pages directly, for eg http://localhost:8080/myProject/changePassword.seam gives me a 403 error. Is there any configuration that I am missing?
My main concern is to show the Change Password page when a certain custom exception is thrown, which I will be handling in the <exception> tag in pages.xml. But when i put <redirect view-id="/changePassword.seam">, all I get is a blank page.

Make sure loginRequired on the page settings is set to false. Also, redirects are usually specified as "/changePassword.xhtml".

Related

Cookieless ASP.Net sessions for static pages

I'm using ASP.Net cookieless sessions so that the session ID for the application is tracked by placing it in the URL via a 302 redirect, for example if the user were to access the below URL
http://yourserver/folder/default.aspx
They would then be redirect to a URL similar to the following which would then proceed to serve up the actual page content
http://yourserver/folder/(S(849799d1-7ec0-41dc-962d-a77e1b958b99))/default.aspx
The problem I have is that the entry point for the application is actually a static page (e.g. one with a .html extension), and ASP.Net is not issuing a session ID & redirecting the user for this page. This therefore means that links to ASP.Net hosted content (e.g. links, iframes etc...) each result in a new session ID being created for each of these links. I cannot easily change the pages extension for compatability reasons (although this does fix the problem).
How can I prompt ASP.Net to create a session for my page? I've tried adding an explicit handler mapping to ensure that the page is being handled by the ASP.Net modules, however this has no impact - while debugging I can see that a SessionIDManager instance is being created for this page (implying that the ASP.Net is already handling this page via the integrated pipeline regardless of my handler mapping), however ASP.Net is still not creating a session for this page.
I am using IIS 7, however this also needs to work on IIS 6 (with expicit handler mappings) and IIS 8.
I have discovered from experimentation and decompiling the ASP.Net source that the SessionStateModule decides whether or not to create a session for a request based on whether or not the IHttpHandler for the request implements IRequiresSessionState or IReadOnlySessionState. If neither of those are true then its all down to whether or not someone has used SetSessionStateBehavior to set the session state behaviour to either Required or ReadOnly.
By default the static file handler does not do any of these and so the session is not created for static files - to ensure that the session state behaviour is set for the static files that require session state I simply set the session state behaviour during the BeginRequest event for the application
// In Global.asax.cs
void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Default);
}
I'm sure there are better ways, but this worked for me.

ASP.NET Webforms User Authorization with Routing

I have a route
routes.MapPageRoute("clientOrder", "Contract/{contractId}/Orders",
"~/ContractOrders.aspx");
The idea is to authorize user to allow access to a certain set of contracts.
For instance user1 has access to pages Contract/001/Orders and Contract/002/Orders
user2 has access only to Contract/003/Orders, etc.
I'm using Forms Authentication and trying restrict access with
CheckUrlAccessForPrinсipal but it checks only physical access to the page not logical.
I tried to check access in Global.asax in Application_AuthorizeRequest but
Request.RequestContext.RouteData there is allways empty so I don't know the requested contractId. I can parse it manually from HttpRequest object. But it is a very dummy and unraliable solution.
Please advice
I believe that the only way is to add some code to check the contractId at the ContractOrders.aspx page level and if the Id doesn't pass the autorization, you manually redirect somewhere to indicate that the access is not granted.
The built-in mechanism always works at the physical level with route maps, so no matter how your route looks like, the engine always checks the access to the resource the route is mapped to, not the route itself.

Redirecting user to dynamic error page

Can I configure ASP.NET custom errors so that it would redirect to other site when error has occurred. Even more, I would like to redirect to different web page every time.
Here is my simplified actual case:
User opens my pages with query ?urlpage=http://test.com/error.html and I would like to redirect to this page when error occurs.
How should I act in this scenario?
See http://msdn.microsoft.com/en-us/library/ed577840.aspx
And in the Page_Error method, just do:
var redirectUrl = Request.QueryString["urlpage"];
if (redirectUrl != null)
Response.Redirect(redirectUrl);
There are a number of different resources in ASP.NET that will allow you to handle errors.
I found this article on the web.config file very informative : http://articles.sitepoint.com/article/web-config-file-demystified
In addition you can setup error handling inside of the global.asax file that will trap application wide errors and allow you to send emails, log information, etc.
You can also setup page specific error handling for more custom error information - but I find that a good general purpose error handling in global.asax works for most situations.
Finally, you can go into the properties for IIS and modify where errors are redirected. For instance, set the 500 error to point to a specific file (/error.aspx or similar).

ASP.Net MVC Authorisation action filter

I'm trying to understand how error handling works when using the Authorize [Authorize] Action Filter in MVC Preview 4.
I have an action that looks like this:
[Authorize(Roles = "DOMAIN\\NOTAUTHORISED_ROLE" )]
[HandleError]
public ActionResult NeedAuthorisation()
{
throw new NotImplementedException();
}
When I visit the url: http://localhost:2197/testAuthorisation/NeedAuthorisation, I get a blank page in my browser. In Firebug I can see that a request was made and a response-status of 401 - Unauthorised has been returned. But I'm not being redirected or having a customError returned. Everything works as expected when using a role that I'm authorized for.
This is using Windows authentication. I'm in the middle of writing some code to try out Forms authentication to see if I get the same issue.
I have <customerrors mode="On"/> set and have created error pages, both in the testAuthorisation folder and the Shared folder.
I eventually found this MVC tutorial which solved my problem:
Exactly what happens when you attempt to invoke a controller action
without being the right permissions depends on the type of
authentication enabled. By default, when using the ASP.NET Development
Server, you simply get a blank page. The page is served with a 401 Not
Authorized HTTP Response Status.
If you've got CustomErrors set to Off or RemoteOnly then you won't get re-directed to the page specified by HandleError (default is Error.aspx). Set it to "On" and then see what happens. Any custom error pages you specify explicitly will take precedence, however, so you need to remove these, and have just:
<customErrors mode="On" />
You need an error view in the corresponding view folder, i.e. you need the file Views/TestAuthorization/Error.aspx in order to have anything show up.
You can also customize this behaviour by what view that you want to use and to what exception you want it to be triggered with.
[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")]]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]]

Avoid losing PostBack user input after Auth Session has timed out in ASP.NET

I have a form that sits behind ASP.NET forms authentication. So far, the implementation follows a typical "out of the box" type configuration.
One page allows users to post messages. If the user sits on that page for a long time to compose the message, it may run past the auth session expiration. In that case, the post does not get recorded... they are just redirected to the login page.
What approach should I take to prevent the frustrating event of a long message being lost?
Obviously I could just make the auth session really long, but there are other factors in the system which discourage that approach. Is there a way I could make an exception for this particular page so that it will never redirect to the Login so long as its a postback?
My coworker came up with a general solution to this kind of problem using an HttpModule.
Keep in mind he decided to to handle his own authentication in this particular application.
Here goes:
He created an HttpModule that detected when a user was no longer logged in. If the user was no longer logged in he took the ViewState of that page along with all the form variables and stored it into a collection. After that the user gets redirected to the login page with the form variables of the previous page and the ViewState information encoded in a hidden field.
After the user successfully reauthenticates, there is a check for the hidden field. If that hidden field is available, a HTML form is populated with the old post's form variables and viewstate. Javascript was then used auto submit this form to the server.
See this related question, where the answers are all pretty much themes on the same concept of keeping values around after login:
Login page POSTS username, password, and previous POST variables to referring page. Referring page logs in user and performs action.
Login page writes out the form variables and Javascript submits to the referring page after successful login
AJAX login
If you don't care if they're logged in or not when they POST (seems a little iffy security-wise to me...) then hooking HttpContext.PostAuthenticateRequest in an IHttpModule would give you a chance to relogin using FormsAuthentication.SetAuthCookie. The FormsAuthenticationModule.Authenticate event could be used similarly by setting an HttpContext.User:
// Global.asax
void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) {
// check for postback somehow
if (Request.Url == "MyPage.aspx" && Request.Form["MySuperSecret"] == "123") {
e.User = new GenericPrincipal(new GenericIdentity(), new string[] { });
}
}
When the session timeout happens the user's session (and page information) get disposed, which would mean the eventual postback would fail. As the others have suggested there are some work arounds, but they all assume you don't care about authentication and security on that particular page.
I would recommend using Ajax to post back silently every 10 mins or so to keep it alive, or increase the timeout of the session as you suggest. You could try to make a page specific section in your web config and include in there a longer timeout.
I handled this once by adding the form value to the database, identified by the remote IP instead of user ID.
( HttpContext.Request.UserHostAddress )
Then, after login, you can check to see if the current user's IP address has a row in the database, and perform the required action.
Michael

Resources