Unauthenticated area of application when using ADFS and WAP - adfs

Parts of my website require authentication and others do not e.g. Register page, About, contact us etc.
For the authenticated areas we integrate with ADFS. We are introducing WAP and are considering the following.
We could use preauthenticaiton and place all functionality that requires authentication in one application and then create a second application only for those parts that do not require authentication.
Is this a common/preferred approach?

It depends on your preference really. You can create separate applications if you wish and add access requirements to one and not the other, or you can add logic to grant users conditional access based on authentication or user role. It would be easier to just use the IsAuthenticated property to grant access to particular pages. You can use either Request.IsAuthenticated or User.Identity.IsAuthenticated depending on how far you want to go.
#if (User.Identity.IsAuthenticated){
using (Html.BeginForm("My Page", "About", FormMethod.Post)){
<div> Page Data </div>
}
}
else{
<div> Show nothing. </div>
}
Or even more minimally you can do something like:
#if (Request.IsAuthenticated){
<h1> Here's your data!</h1>
}
else{
<h1>Here's your blank web page! </h1>
}
For reference: How does Request.IsAuthenticated work?

Related

ASP.NET MasterPage usage for authorization purposes

I am using master pages for authorization. I have three different user types: Readers, Authors and Admins.
I have a Main.Master which has the fundamental things of my pages. Then I have,
Reader.Master
Author.Master
Admin.Master
These inherited from the Main.Master. I am checking if the user really logged in (Session is not null) and if the UserType is true in Reader.Master, Author.Master, Admin.Masters Page_Init() functions.
First question: Is that a good practice? Please consider that I have zero experience of using other ASP.NET built-in stuff for user management, authorization etc..
Second question: There are some pages like ForgotPassword.aspx which all UserTypes should access the same page. In my structure, I need to create three different pages inherited from three different Master's. How to solve this issue?
To your first question: I use it similar. I'm not sure if it is a good solution but it works for me.
Second question: You can define ContentPlaceHolder in your master pages.
<asp:ContentPlaceHolder ID="MyId" runat="server" />
In your aspx site you define for each ContentPlaceHolder one Content container.
<asp:Content ContentPlaceHolderID="PageContent" runat="server">
<!-- content for this area -->
</asp:Content>
If you define in your three user type master pages ContentPlaceHolder with the same ID you can use in a page like Forgot.aspx the same content for each master page.
Second question: There are some pages like ForgotPassword.aspx which all UserTypes should access the same page. In my structure, I need to create three different pages inherited from three different Master's. How to solve this issue?
Create User.Master and Guest.Master with same way and you will have masters for all kind of users.
User.Master will check only if user is logged in.
well, authentication in master pages is acceptable, if not the best practice. I have seen many books that start with these kind of tutorial. however you may face some issues when your website scales, also handling authentication related data in other than pages like in haldlers or global.asax can be a pain.
However this kind of authentication will be OK when the scope of website is limited and you doesn't require advanced function.
regarding you 2nd question then yes what you are getting is the side effect of the method being used. what you can do is create only one page using any of three masterpages. in that master page where you are checking for authentication, there you get the name of the page, and if the page name is same as forgot.aspx or what ever just ignore get out of the normal process.
eg
if (System.IO.Path.GetFileName(Request.PhysicalPath).ToLower() == "forgot.aspx")
{
}
else
{
doauthentication();
}
just make it as a normal webform page without master page, users can't log in if they forgot password, you only need to show them a normal page like the login page

In Sitecore, how to change or set PageMode

In Sitecore, I have users who are using the editing ribbon to add content to pages. However, there are some pages that I want to prevent EditMode completely from that user's role. This is based off of a branch template, so I can't just revoke privileges for each page. I need some way to set the Sitecore.Context.PageMode to be Normal.
Is there an API for setting the PageMode?
While I was unable to find a C# API, I did find that I could just use a URL Redirect that looks something like this:
if (!Sitecore.Context.PageMode.IsNormal && !IsAdministrator())
{
String id = Sitecore.Context.Item.ID.ToString();
Response.Redirect("/?sc_mode=normal&sc_itemid=" + id + "&sc_lang=en");
}
This will set the PageMode to Normal if it in any other state.
your redirect method should work, but it also turns off the PageEditor mode for other pages the editor visits after the redirect.
You could also check if the Page is in EditMode and the user is part of a certain Role and for that (sub)layout show standard .NET controls instead of the Sitecore sc-controls.
Like <asp:Literal /> instead of <sc:Text />
I would suggest that rather than redirecting the user/hard-coding this to specific pages you make create a rule and make use of the Rules Engine. This will allow you to reuse the code and turn on-/off much easier through the content editor.
There is already a condition to select the role:
/sitecore/system/Settings/Rules/Common/Conditions/Security/User Role
So you will just need to create an action to switch to Normal mode. In your action, you can call the following code:
Context.Site.SetDisplayMode(Sitecore.Sites.DisplayMode.Normal, Sitecore.Sites.DisplayModeDuration.ResetAfterRequest);
Wrap it in a check like wilsjd has suggested.
Some info on the Rules Engine if you are not familiar with it:
Decoupling through the Rules Engine
All About the Sitecore ASP.NET CMS Rules Engine

What is the best way to switch between authenticated and anonymous views in asp.net MVC3 web pages?

I've been playing around with MVC3 for a little while and I'm thinking of putting what I've learned to use now and knocking up a genuine project using it but there's one thing that I've never really seen clearly explained or demonstrated and was hoping I could get a little feedback from the community here on the subject. The question is that when you have a page that can be in two states depending on whether the visitor is authenticated, what techniques should I be using to switch between the two states? Should each page have two completely independent views and a shared model common to both views or is it best approached with partial views to control the difference between the logged in or anonymous elements? Or would it be better to have two different models AND two different views and then switch between them at the controller stage?
I can see lots of different ways that I could implement it but I've never really seen any examples or suggestions on a best-practice way of going about it and I haven't built a project big enough yet to serve as a laboratory to find out the hard way, although that IS what I'm about to embark on.
Does anyone have any stories to tell of ways they have gone about it? Even "Don't do it this way" would be helpful just to thin out some of the options.
The reason I ask is that I'd like to make a site that isn't completely crippled until you login and register, it drives me nuts when you can't get past the home page of a site without going through a registration process so I want to be able to serve up a "Lite" version of each page with no user-specific content even if the visitor has not authenticated and then add the extra functionality to the page when they log in.
I can see other questions on the same subject but they all seem to relate to iOS development so apologies if this question has been asked before but I couldn't see anything that answered my question.
Feedback appreciated, I'd love to hear what works and what doesn't for other people.
Edit: A less ambiguous way of asking the question.
On my home page I have a username/password box in the top corner with a "login" button and a paragraph of text in the middle of the home page. When a user enters their username & Password and hits submit I want that "login" control to change to a "Welcome: {username}" message and a logout button and I want the paragraph of text on the homepage to switch to an "authenticated" message. What I don't know is where to make these changes to the page structure, are these two views? Authenticated_Homepage and Anonymous_Homepage, do they share a single model or do I just have one homepage view and use partial views for the changing parts, or do I use roles on the controller to return different views?
Just don't know which tools to use for the job to be honest.
That wouldn't be two Views. MVC typically uses authentication/authorization actually on the Action method level. But in your scenario, you'd do something like this in View code:
#if(Request.IsAuthenticated) {
<text>Welcome <strong>#User.Identity.Name</strong>!
[ #Html.ActionLink("Log Off", "LogOff", "Account") ]</text>
}
else {
#:[ #Html.ActionLink("Log On", "LogOn", "Account") ]
}
This is pulled directly from an MVC 3 template. In this case, this is Partial View code that is rendered on the _Layout.cshtml Shared View. That way this is rendered on each page (think of _Layout as a "master page" if you are coming from a WebForms background).
All the Partial View code does is test for an authenticated user. If it is an authenticated user, then there is a welcome message displayed. If it is not though, then there is an ActionLink() to get to the Login Action method in order to have the ability to authorize.
Typically though you'd restrict/allow users/roles to certain Action Methods, here's what you'd do:
public ActionResult EverybodyCanAccess()
{
return View();
}
[Authorize]
public ActionResult OnlyAuthenticatedUsersCanAccess()
{
return View();
}
[Authorize(Roles = "Admin")]
public ActionResult OnlyAdminsCanAccess()
{
return View();
}
[Authorize(Users = "John, Bob")]
public ActionResult OnlyJohnAndBobCanAccess()
{
return View();
}

How can I create a view that has different displays according to the role the user is in?

I want to create a view that has different displays according to the role the user is in.
Should I create a different view for different roles or should I check the roles on the Veiw page itself rather than in the actions?
How would I check the role on the view page?
Or should i use check the roles on the
Veiw page its self rather than on
actions, if so can someone plz show me
how do check that on view page
You need to do both. Check roles on actions as a security measure and check roles on views to enable/disable specific controls.
Within your view page the long form of checking a role is
HttpContext.Current.User.IsInRole("Administrator")
many developers will create page helper methods so you can end up with something more concise for your application like
public static bool IsAdmin(this ViewUserControl pg)
{
return pg.Page.User.IsInRole("Administrator")
}
then in your view you can just use this.IsAdmin()
To keep your view clutter down look into using partial views
<% if (IsAdmin())
{
Html.RenderPartial("AdminPanel");
}
else
{
Html.RenderPartial("UserPanel");
}
%>
If the display changes based on the role -- and the change is small -- then I would do the check in the view. If certain views are restricted based on the role, then I would do the check in the controller. If the views are completely different (this would be hard to imagine), then separate views per role may be appropriate.
You may want to abstract out certain role-specific view components into partial views to simplify your view logic -- basically you only have to check to include the partial or not based on the role.
Also, other than to check for "IsAuthenticated", I would move the role checking logic to the controller and pass (as data) to the view information on which elements to include/exclude based on role. This keeps the actual business logic from bleeding into your view.
If you are using MVC the whole point of development is to keep the logic out of the view and in the controller. It seems to me like you'd be better off on a WebForms development track than an MVC track.
All that being said, I do an Admin check on a lot of my pages by using a check like this:
<% if ((bool)ViewData["Admin"]) { %>
<!-- Show admin controls here -->
<% } %>
But if you are attempting to build actual logic into the View then you need to figure out what you can push back to the controller to do the work and have the view be as dumb as possible, acting on flags sent to it.
without researching the exact mechanism asp.net mvc uses for roles i would scream no for putting any of your business logic in the view which is what you are doing if you are checking roles in the view
Yeah that was something that was bothering me as well ... but at the same time it seems ridiculous to load whole different view for such a small change.
btw
how did you set this up in your controller.
Right now, my controller looks something like the code below, which I don't think is correct.
[Authorize(Roles = "Admin, Member")]
public ActionResult RegistrationInformation()
{
return View();
}
I'm not that familiar with ASP.NET MVC (yet) but can't you do some kind of conditional filter in the View? If the Controller passes the role to the View, then you should be able to do a conditional filter and display a certain block of code if the user is an admin. If you want to display a totally separate page, then you'd have a multiple Views, otherwise you can use one and do some conditional.
In Ruby on Rails it would be something like (sorry, I don't know ASP.NET MVC really yet):
<% if #user.admin? # is the user an admin %>
<h3>Admin Tools</h3>
<% end %>
<p>Regular site content</p>
In Rails you would load the extra content from partials; ASP.NET MVC has something similar but I forget what it's called. Maybe look into that?
Sorry I can't be of more help -- like I said I haven't really gotten to play with ASP.NET MVC.
I have base model which from all others models extend. In this model i have loaded the user's roles. Its based on httpcontext.user.isinrole() method. All views are strong typed expecting the base model type.
So i can always check in all views something like Model.CurrentUser.IsInRoles(Role1 | Role2). Not only in views of course, but in hole application.
I like to have full control over this in the view, and I find that:
<% if (User.IsInRole("Super User")) { %>
<h1>Hello world!</h1>
<% } %>
Works for most scenarios. It also allows you to easily do conditional formatting for other roles, e.g "Content Manager", "Registered", etc.
I do like Todd Smith's answer, because you might change the name of the Admin role, and that will require only one change, whereas, if you put the "Super User" or "Administrator" string directly in the view, you will have to change it wherever you've used the value.

How do I best handle role based permissions using Forms Authentication on my ASP.NET web application?

I'm using the ASP.NET Login Controls and Forms Authentication for membership/credentials for an ASP.NET web application.
I've got two roles:
Users
Administrators
I want pages to be viewable by four different groups:
Everyone (Default, Help)
Anonymous (CreateUser, Login, PasswordRecovery)
Users (ChangePassword, DataEntry)
Administrators (Report)
Expanding on the example in the ASP.NET HOW DO I Video Series: Membership and Roles, I've put those page files into such folders:
And I used the ASP.NET Web Site Administration Tool to set up access rules for each folder.
It works but seems kludgy to me and it creates issues when Login.aspx is not at the root and with the ReturnUrl parameter of Login.aspx.
Is there a better way to do this? Is there perhaps a simple way I can set permissions at the page level rather than at the folder level?
A couple solutions off the top of my head.
You could set up restrictions for each page in your web.config file. This would allow you to have whatever folder hierarchy you wish to use. However, it will require that you keep the web.config file up to date whenever you add additional pages. The nice part of having the folder structure determine accessibility is that you don't have to think about it when you add in new pages.
Have your pages inherit from custom classes (i.e. EveryonePage, UserPage, AdminPage, etc.) and put a role check in the Page_Load routine.
One solution I've used in the past is this:
Create a base page called 'SecurePage' or something to that effect.
Add a property 'AllowedUserRoles' to the base page that is a generic list of user roles List or List where int is the role id.
In the Page_Load event of any page extending SecurePage you add each allowed user role to the AllowedUserroles property.
In the base page override OnLoad() and check if the current user has one of the roles listed in AllowedUserRoles.
This allows each page to be customized without you having to put tons of stuff in your web.config to control each page.
In the master page I define a public property that toggles security checking, defaulted to true. I also declare a string that is a ; delimited list of roles needed for that page.
in the page load of my master page I do the following
if (_secure)
{
if (Request.IsAuthenticated)
{
if (_role.Length > 0)
{
if (PortalSecurity.IsInRoles(_role))
{
return;
}
else
{
accessDenied = true;
}
}
else
{
return;
}
}
}
//do whatever you wanna do to people who dont have access.. bump to a login page or whatever
also you'll have to put
at the top of your pages so you can access the extended properties of your master page

Resources