Windows Authentication & Role Managment

Jul 22, 2010 at 1:27 AM

Help me out here. I may just be hung up on a silly issue.

Is BlogEngine.NET intended to be a single website that supports multiple blogs? Or is intended to be a single blog instance that supports multiple roles (authors, readers, etc.) for the one blog?

I am trying to figure out how I need to orchestrate BlogEngine into our site. To over simplify, we have a single IIS 7, running a ASP.Net 4.0 Web Forms site (done project style, not site style). It looks like this:




We would like to deploy multiple blogs - for the chief, developers, HR, you name it... and would like the following URIs






To do this, does blog engine have to be installed multiple times? or is this scenario handled within the application itself? Are the one instance of an IIS application inside my website... or are they each an instance of blog engine tied to their own IIS Applications?



Thanks for the clarification. Maybe I'm dumb here.


Jul 22, 2010 at 11:14 AM

With a single instance of BE, you can have multiple Authors.  With multiple authors, the blog is the same, same theme, same settings, a single pool of Posts ... but each author can login under his own name and create a post under his own name.  This is probably not what you're looking for, but just thought I'd bring it up.

Otherwise, the only option you have is to create a separate Web Application for each blog.  So /intranet/blog/chief would be a separate installation of BE and would be marked as an application in IIS.  Similarly, /intranet/blog/hr would be a separate installation of BE and would be marked as an application in IIS.  All data and settings would be isolated from one another.

Jul 22, 2010 at 11:47 PM


Thanks for the reply. Even as separate IIS application instance, I think BlogEngine.NET is still a very viable tool for us. I just wanted to understand its intention clearly as I was poking around in the source code.

So, assume we have our shell intranet website - ASP.Net 4.0 Web Forms, Windows Integrated (Kerberos, w/o impersonation) authentication - this means HttpContext's User would be "domain\user" and the WindowsIdentity the app pool's identity account, "domain\customAppPoolIdentity".

Each BE.NET instance then will be setup as its own application within the website, but the key is making it work with our authentication and role management. Do you have any clear instructions on what it would take to adapt BE.Net to fit our authentication? I've come close but not quite, and none of the discussions have provided a good solution. Here are the steps I have currently followed:

1. Downloaded 1.6 source to my dev machine.

2. Converted to VS.Net 2010 project (but have not re-targeted it for .Net 4)

3. Changed web.config:

<!-- The name of the role with administrator permissions -->
<add key="BlogEngine.AdminRole" value="CDF\twhite"/>
<!-- The name of the role with editor permissions -->
<add key="BlogEngine.EditorRole" value="CDF\Domain Users"/>

<!-- "Admin" path Authorization -->
<location path="admin">
<allow roles="CDF\twhite"/>
<deny users="*"/>

<authentication mode="Windows"/>
<!-- original roleManager tag and connection string tags commented out -->
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider"/>
<allow roles="CDF\Domain Users"/>
<deny users="?"/>

(from what I understand, IIS should authenticate any Domain User to the blog, and explicitly CDF\twhite to the admin section. and BE.Net should then allow CDF\twhite to be admin, and Domain Users editors. Am I off here?)

4. Precompiled the website, and copied the pre-comp website up to our web server box.

5. Mapped an IIS application to the site folder (virtual path /testblog).

6. Custom application pool is 2.0 Integrated. Identity is "domain\customAppPoolIdentity". Identity has Read permissions for the entire blog site. It also has explicit Write permissions to the blog site's AppData folder. All AppData contents have read-only unchecked.

7. Run the app logged onto my box as CDF\twhite. The blog comes up, and it looks as if I am logged in, but all I see in the Administration box is "change password". No add entry, or settings, no X's on the boxes.

8. If I try to explicitly visit /testblog/admin/pages/settings.aspx I get a 401 access denied... suggesting something is wrong with authentication or role permissions.


Your help is greatly appreciated, Ben. If I can get one instance running with kerberos, and tied to our AD groups for permissions, then I can make a VS.Net template for new blogs and be good to go I think.


Jul 26, 2010 at 1:04 AM

I think you are probably more familiar with Kerberos then I am.  But just a few observations...

Is CDF\twhite a user or role?  When BE uses the "BlogEngine.AdminRole", it's using it to see if the current user is in that role -- not to see if the current user is "twhite".  If twhite is a user, then you might want to consider creating an AD group that represents a BE admin, and assigning "BlogEngine.AdminRole" to that group.

BlogEngine.EditorRole --- did you make this up?  I don't think (but could be wrong) that BE makes use of or recognizes that appSetting.  You may not even need it since you already have "CDF\Domain Users" in the <allow> tag for <authorization>.

One thing that might help a little bit is to paste the following markup into default.aspx (maybe above the <h1> tag, but somewhere within the <asp:Content> tag).

All Possible Roles = <%= string.Join(", ", Roles.GetAllRoles()) %><br />
User.Identity.IsAuthenticated = <%= User.Identity.IsAuthenticated %><br />
Roles.GetRolesForUser = <%= string.Join(", ", Roles.GetRolesForUser()) %><br />
User.Identity.Name = <%= User.Identity.Name %><br />
Then when you pull up the homepage for BE, it'll give you some information on the current user -- their name, and their roles -- as BE sees it.  The top one "All Possible Roles" is listing all the possible roles.  I believe this comes from the <roleManager> defined in the web.config file.  But if you're using Windows authentication instead of Forms authentication, I'm not sure what role the <roleManager> has for Windows authentication (pun unintentional).

The logged-in menu that would normally show items like Add Entry, Pages, Blogroll, etc .... for this, the items that are output are based on the roles defined in the Web.sitemap file.  For example, you'll find this in there:

<siteMapNode url="~/admin/Pages/Add_entry.aspx" title="add_entry"  description=""  roles="administrators, editors"/>
You probably need to update the "roles" to CDF\Domain Users, etc.

Similarly, in the "admin" folder, there's about 4 web.config files that you will probably need to update the "roles" in.

1.  Web.config file in the "admin" root folder -- NO UPDATE should be needed since roles are not being specified.
2.  Web.config file in the admin\Pages folder -- this one in particular needs to be updated.
3.  Web.config file in the admin\Comments folder -- this one should be updated too -- this is new in BE 1.6.
4.  Web.config file in the admin\Extension Manager folder - this one should be updated.

The Web.sitemap file controls what items appear in the admin menu (Add Entry, Pages, etc).  These web.config files mentioned above control whether the person has access to these pages once they get there.  So if you were to update just the Web.sitemap file, the menu items "should" appear, but then if you try to navigate to one of those pages without having updated the Web.config file, you would get knocked out.  So it's necessary to update both the Web.sitemap file and these Web.config files.

Aug 3, 2010 at 12:23 AM


Thanks for writing back. Your ideas are very helpful. I've not had a chance to play with it all, but I think I understand the big picture now.

Our Windows Authentication is working (I'm CDF\TWhite via Kerberos) and the roleManager is returning all my AD group memberships properly.

The breaking difference seems to be with RoleManager as you pointed out... in the root web.config it was commented out to provide "<roleManager defaultProvider="AspNetWindowsTokenProvider" enabled="true" />" - Doing this breaks the XML architecture BE.Net had internally working (Users.xml, Roles.xml, and your custom written provider).

My guess is right now its going something like this: "Ah, we have a CDF\TWhite here and he is a member of CDF\SomeGroup, but according to my web.sitemap file only 'administrators' and 'editors' should see the link. Don't render the link." and "Now he went to the page directly from a URL. The folder's web.config file here says only 'administrators' and 'editors' should get this page. Do not render the page. 403 Error."

I'll bet "administrators" were qualified with "SERVERNAME\administrators" than it would probably work (as I have admin rights on the box) - basically AspNetWindowsTokenProvider cannot find any groups Local or Domain level by those two names, and thus no one is authorized to see those links or visit the pages. If that's the case, and I didn't fudge anything up on the App_Data permissions (only the app pool identity should need Write access to App_Data), then changing the web.config and web.sitemap files should do it.

I'll tweak it tomorrow and see how goes.

Thank you a ton for the insight.


Aug 3, 2010 at 7:16 PM

I'm digging around through the setup documentation, but I was curious if you had any technical documentation on the default permissions tied to "administrators" and "editors" roles in the XML system... It's easy for me to go through and replace these roles with the 2+ AD groups that will be used instead... but I may want to configure what my "editors" can do, or perhaps even offer a 3rd level of permission - Admin, Editors/Publishers, Commenters/Readers types...

Aug 5, 2010 at 6:11 AM

Unfortunately, I cannot think of any documentation that documents what things each role can do by default.

Probably using a Find/Search tool will be your best friend  :)

There's not too much directly tied to Editors though -- except for the terms "editor" you see in the list of roles in those web.config and web.sitemap files.

The most common security check in BE is to see if the user is either in the Administrators role, or to see if the person is logged in, either via:

-- or --

BE is designed with these 2 roles in mind (administrators, editors), so it doesn't typically do different things based on the role, or display different buttons/actions depending on the role.

One minor exception that comes to mind is when an Editor is logged in, to determine if that Editor is able to edit a Post, or do other actions against a Post, it will check to see if the Author of the Post matches the logged in Editor's name.  If so, it allows that Editor to modify that post.  Otherwise, it considers the post to not be modifiable by that Editor.

You can of course add more role checks to customize what each user can do.  You've seen code like Page.User.IsInRole(BlogSettings.Instance.AdministratorRole).  You can use the same code to check for other roles, i.e. Page.User.IsInRole("Commenters").

Aug 5, 2010 at 6:53 PM

I think the paradigm that will be asked of me is 3 roles: Admin, Editors/Authors, and Readers.

For instance, our Chief may have a blog. He and his group of assistants should be able to post (Authors/Editors), our Web Admins will be "Admin", and then everyone in our Organization should be limited to reading (and maybe provide comments)

Perhaps I am misunderstanding something you said above, but I am curious what constitutes an "editor" - as the role is present like you pointed out, in all the web.config files, but I don't see it defined in the settings like the BlogEngine.AdminRole. By default is every authenticated user then considered an editor if they are not explicitly an Admin?

The other thing I am trying to do is tie the authenticated user to the Author data, so that it is automatic. Whomever posts then is author... non-selectable.

Making progress... thank you for your help.


Aug 5, 2010 at 11:15 PM

A user is only an Editor if you check the "Editor" box on the Users tab in the control panel.  Every user is typically an Editor or Administrator.  They could be neither, but in this case they would not be able to do much.  A typical visitor to the blog is not authenticated at all.

Because the Administrator role is referenced frequently enough, the BlogSettings.Instance.AdministratorRole constant was created as a shorthand, to avoid needing to type "Administrator" and risk the chance of a mis-spelling (I suppose).

The Editor role is hardly ever referenced.  It's usually just used to limit access in those web.config and web.sitemap files.

In those places in code where it checks "User.Identity.IsAuthenticated", this is typically used to see if the person is logged in, and it's usually assumed that the logged in person is an Editor or Administrator.  So in a way, "User.Identity.IsAuthenticated" is often used as shorthand and based on the 2 default roles (Editor and Administrator), it's equivalent to:

if (Page.User.IsInRole(BlogSettings.Instance.AdministratorRole) || Page.User.IsInRole("Editor"))
{ ........ }

Aug 6, 2010 at 7:03 PM

Thank you very much Ben!

If the role checks hang on the assumption that general consumers aren't authenticated (ex. Forms Auth on a public site), and when our intranet environment everyone is authenticated, it sounds like I have three things to do... tell me what you think or if I'm missing something:

1. In BlogEngine.Core, BlogSettings.cs, add role constants for convenience (ex. BlogEngine.Editor, BlogEngine.Commentator, BlogEngine.Reader) like this:

/// <summary>  Custom: The role with editor permissions </summary>
public string EditorRole
get { return ConfigurationManager.AppSettings["BlogEngine.EditorRole"] ?? "editors"; }
<summary> Custom: The role with comment/rate-only permissions </summary>public string CommentatorRole
get { return ConfigurationManager.AppSettings["BlogEngine.CommentatorRole"] ?? "commentators"; }

2. In BlogEngine website instance, replace "IsAuthenticated" checks with appropriate explicit IsInRole() checks (like your IF statement above).

3. In BlogEngine website instance, alter the web.config and sitemap authorizations as necessary to shape the permissions granted to these roles.

4. Then there is one last step... tying it to AD users/groups... and it looks like there's two ways to do this:

   a. Continue using BlogEngine's role provider/manager - and tie Roles.xml in AppData to the individual AD user accounts like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

   b. Replace BlogEngine's role provider/manager with one using AspNetWindowsTokenProvider... and then tie the constants to AD Groups in web.config like this:

<!-- The name of the role with administrator permissions -->
<add key="BlogEngine.AdminRole" value="CDF\BlogAdmins"/>
<!-- Custom: The name of the role with Editor permissions -->
<add key="BlogEngine.EditorRole" value="CDF\BlogEditors"/>
<!-- Custom: The name of the role with Commentator permissions -->
<add key="BlogEngine.CommentatorRole" value="CDF\BlogCommentators"/>

(B) is definitely cleaner and I manage things in AD, but I'm worried it could break more stuff in BE.Net


Is there anything else in BlogEngine.Core that I might need to adapt?


If and when I get this setup right in an Integrated Windows Environment with minimized augmentation, I'll send you the source code and write up a short Config document that explains what I had to do. Maybe it would be of some use.


Thank you yet again, Ben.

Aug 6, 2010 at 9:12 PM

Ok... let me refine the steps I said before...

1. Optional - so long as they appear in the instance's web.config (that is the actual constant), the property in BlogEngine.Core's BlogSettings.cs only makes it a public property and provides a default value if web.config does not declare one... strong typing convenience too.

4. Option B is best. I saw a friend's implementation of BE.Net and they are using the AspNetWindowsTokenRoleProvider, with BE's stock RoleManager and MemebershipProvider sections commented out... my issues before with stuff "breaking" must have been from having the web.config and sitemap files adjusted right... using user names rather than groups, etc.

The rest sound about right?

Aug 9, 2010 at 1:39 PM

Yes, everything sounds right to me.  For # 4, option B does sound like a better long term solution.

I think all usage of Roles in BE is consistent in that it uses User.IsInRole().  This is a nice abstraction since no matter what underlying role provider is being used, it should theoretically make no difference from BE's point of view.  I would assume and hope that a switch to AspNetWindowsTokenRoleProvider would not cause BE or User.IsInRole() to work differently or return inconsistent values.

It's good you caught a glimpse of what your friend has working.

I think I have a relatively good idea of what you're doing based on this Discussion.  But if you do get it all working and don't mind passing along the source code or whatever you might have, that would be a really nice resource for me.  It wouldn't be the first time where something seemingly a one-time situation ends up popping up again for someone else or even myself <g>  Thanks.

Aug 9, 2010 at 11:31 PM

Right on. I've been poking around to see how much needs to be changed... I thought of something. What do you think of this idea, as it sounds like it might be a nice feature for BE.Net regardless of roles used. Tell me what you think, and as a noob developer, I offer this humbly.

Create or extend a class in BlogEngine.Core that allows the ability to check if an (authenticated) user has a necessary permission associated with what the task is doing (ex. Delete, Post, Comment, Rate, etc.) - then use an XML file perhaps in blog instance (App_Data) to associate role constants with the permissions.

Now a developer can specify roles in the instance's root web.config file, and then edit the XML file to associate permissions with the role as necessary. What's better is BlogEngine.Core could now check for permissions which are more appropriated associated with the task (less coupling to the role implementation) - so when a user attempts to delete a post the Core library checks something like "if(User.CanDelete)". To make it all work, I see something like this happening - on session start, authentication is resolved however fit... then the user's role is resolved, and the "CanSOMETHING" properties on the class are assigned values based on the permissions associated with the role in the XML file.

Here's some pseudo code to explain better:

    // do permissions from most restricted to least in case 
    // user is in multiple roles (probably most likely to 
    // happen in WindowsAuthentication scenarios)
SetPermissions(string userRole)
    // grab the permissions from the XML file and 
    // stuff them in an array or dictionary or something.
    var permissions = GetPermissionsForRole(userRole);
    // set the user permissions based on those returned from XML
    User.CanDelete = permissions['delete'];
    User.CanPost = permissions['post']

In BlogEngine.Core, or blog instance now you could do

Delete_Click(var post)


Shouldn't be too difficult to tie into your current code... I'm gonna give it my best shot, but I'm unfamiliar with all the different "actions" a user can take interacting with a blog. If you wanted to take it a step further, and decouple the Core and instance projects further, you could remove hard references to roles from places like BlogSettings.cs and create a class that grabbed the roles defined by the developer in the instance's web config but remained ignorant to actual roles.


Am I making sense? Or do I sound like another ungrateful user who can't program his own stuff? :)


Thanks for all your help Ben. I can't promise any of my work will be beneficial, but I'll send it your way when I'm done...

Aug 10, 2010 at 12:43 AM

much smaller related question...

i have all the groups setup in the web.configs the way they should be, authorization and authentication seems to be working as i want it, with one exception... 4 pages: add_entry, users, and a couple others are not rendering... I get a 500 error on them, and on the IIS server box itself via //localhost/ I get a custom error page of yours (even with CustomErrors Off)... your error page states that it has to do with timeouts to SQL... which I'm confused about because i didn't change anything to do with SQL.

On my workstation when I debug a local copy it works fine and posts fine via XML...

The app pool has rights to Write to App_data as always, and the whole folder/file tree has had read-only removed. I ran APPCMD to migrate the configs just for safety... but something is still wrong.

What would cause it to look for SQL?


Aug 10, 2010 at 9:41 AM

The idea you have with roles and permissible actions makes a lot of sense.  I would imagine that probably some other CMS type systems have a system like that in place.  There are some changes being made currently to BE to allow users to create their own roles in the control panel.  Rtur has been working on that, and I'm not sure if that will tie in with actions.

One place actions (or some of the actions) could be defined at is in the BusinessBase class.  Many classes like Post and Page inherit from BusinessBase.  These sub-classes might then expose CanDelete() or CanUpdate() methods, which would be specific to the item at hand -- e.g. a particular Post or Page.

With the default installation of BE, these actions could be used for maybe a dozen or so situations (probably more if I really think about it).  An advantage of implementing such a system is that even if the default BE installation isn't making extensive use of these actions/permissions, by having the system in place, it makes it much easier for people customizing BE (e.g. yourself) to build on top of the system.  So, yes, it's a good idea.

...... you're only using XML and getting a SQL related error?  If you are able to see or post a specific error message possibly with a stack trace which might appear underneath, that would help a lot for trying to identify the cause of the error.  I don't remember seeing a SQL related error when using the XML blog provider.  If there is a specific error message and/or stack trace, there's probably some hints in there as to the cause of the error.

Aug 10, 2010 at 5:52 PM

Site renders to the home page, and I click Add_Entry.aspx in the widget box on the right... times out after about 5-6 seconds, and then renders the blog page, but the page body where the posts would normally be is your blog error section... this is the error message I am getting:

Ooops! An unexpected error has occurred.

This one's down to me! Please accept my apologies for this - I'll see to it that the developer responsible for this happening is given 20 lashes (but only after he or she has fixed this problem).

Error Details:

Url : http://localhost/blog/Test/admin/Pages/Add_entry.aspx

Raw Url : /blog/Test/admin/Pages/Add_entry.aspx

Message : Exception of type 'System.Web.HttpUnhandledException' was thrown.

Source : System.Web

StackTrace : at System.Web.UI.Page.HandleError(Exception e)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

at System.Web.UI.Page.ProcessRequest()

at System.Web.UI.Page.ProcessRequest(HttpContext context)

at ASP.admin_pages_add_entry_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\blog_test\ed228e9a\6912432c\App_Web_0g3rc2vi.6.cs:line 0

at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

TargetSite : Boolean HandleError(System.Exception)

Message : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

Source : .Net SqlClient Data Provider

StackTrace : at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)

at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()

at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity)

at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject)

at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)

at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)

at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)

at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)

at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)

at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)

at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)

at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)

at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)

at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)

at System.Data.SqlClient.SqlConnection.Open()

at System.Web.DataAccess.SqlConnectionHolder.Open(HttpContext context, Boolean revertImpersonate)

at System.Web.DataAccess.SqlConnectionHelper.GetConnection(String connectionString, Boolean revertImpersonation)

at System.Web.Security.SqlMembershipProvider.GetAllUsers(Int32 pageIndex, Int32 pageSize, Int32& totalRecords)

at admin_entry.BindUsers()

at admin_entry.Page_Load(Object sender, EventArgs e)

at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)

at System.Web.UI.Control.LoadRecursive()

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

TargetSite : Void OnError(System.Data.SqlClient.SqlException, Boolean)


Is there a reason this stuff is getting pumped out by the blog site rather than a raw server error with detailed information? Three main sections of web.config are commented out: Membership, RoleManager, and ConnectionStrings. The changes were made when changing RoleManager to use AspNetWindowsTokenRoleProvider. Membership is unecessary, as is anything to do with SQL for now.




Aug 10, 2010 at 6:21 PM

More information...

From the looks of your error message, the best hint I could see was admin_entry.BindUsers()

BindUsers() is simply a foreach loop that places every MembershipUser in the Membership.GetAllUsers() collection into the Author dropdown. In visual studio, stepping through this step is easy and works fine... 0 members in GetAllUsers, so the loop ends and everything moves on... Add_Entry.aspx renders in Visual Studio's web server.

When on IIS on the test box, the next call in your error message tells us, something is happening in Membership.GetAllUsers() that it is sparking up SqlMembershipProvider and then timing out trying to connect to a database that doesn't exist. The question is why is it looking for SQL? As I pointed out, I've added nothing DB related to the project, and removed both the RoleManager and Membership sections, as well as removed the ConnectionStrings section and the BlogEngingeProvider section's reference to DbBlogProvider...  from what I can see this should gut everything to do with SQL.

If anything, I was expecting to get back something that said every time BlogEngine tapped Member.Something() that it would blow up without a Membership section in web.config - but again, it's not blowing up like that... do you think without a Membership section, IIS is reverting to defaults in machine.config or something?

Aug 10, 2010 at 8:05 PM

Even more information...

After playing around a bit further, I noticed almost all references to Membership and related methods were for the purpose of adding authors to drop downs or exporting blog stuff... our blogs will operate under the assumption that the author is always the one who is truly posting (no delegation going on even for administrators), and with AspNetWindowsTokenRoleProvider I have no way of using Roles.GetUsersInRole() to replace these calls... so I commented them out. Results: all the pages render fine.

The next issue, may or may not be related to this thread, so if you think it is best to start another discussion for clarity, let me know.

When I type a post on add_entry.aspx in the Visual Studio hosted site, Save works fine and posts properly. When on the IIS server, the same post causes an immediate error on Save:

Ooops! An unexpected error has occurred.

This one's down to me! Please accept my apologies for this - I'll see to it that the developer responsible for this happening is given 20 lashes (but only after he or she has fixed this problem).

Error Details:

Url : http://localhost/blog/Test/admin/Pages/Add_entry.aspx

Raw Url : /blog/Test/admin/Pages/Add_entry.aspx

Message : A potentially dangerous Request.Form value was detected from the client (ctl00$cphAdmin$txtContent$TinyMCE1$txtContent="

Source : System.Web

StackTrace : at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)

at System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection)

at System.Web.HttpRequest.get_Form()

at System.Web.HttpRequest.get_Item(String key)

at BlogEngine.Core.Web.HttpModules.CompressionModule.context_PostReleaseRequestState(Object sender, EventArgs e) in D:\Websites\calfireweb_wf\BlogEngine.NET\BlogEngine.Core\Web\HttpModules\CompressionModule.cs:line 62

at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

TargetSite : Void ValidateString(System.String, System.String, System.Web.Util.RequestValidationSource)



What would make IIS freak out about the post?
Aug 10, 2010 at 9:01 PM

Ok... even more information... and a likely solution...

The only thing different my friend and I could find between our configurations was that his application pool was 2.0 Integrated, and mine was 4.0 Integrated... so why not try it... I changed mine to 2.0 Integrated and it blew up... stating that the root web.config (for the site that hosts BE as an app) had "targetFramework=4.0" in its Compilation tag... and that this attribute was not valid... Truth be told, it is not valid in 2.0, thus why it could not be explicitly declared in the BE.Net web.config file... and thus trying to inherit it from its parent host site. Removing this attribute from my host's web.config, the site remains targeting 4.0, and the BE.Net app now runs on 2.0 Integrated.

Guess what? Add_Entry.aspx now posts properly.

The question is WHY... what is different about 2.0 that would cause it to trust the Request.Form value that it would not trust when running under 4.0? The Page directive has ValidateRequest="False" as it should, so I don't know why it blew up, but changing the app pool solved the problem.

Is this something to do with BE.Net's code, or something about the .Net framework that I should know about?

Aug 11, 2010 at 2:32 AM

Good detective work.  The stricter form validation in .NET 4.0 is a problem across all ASP.NET applications, from my understanding -- not just BE.  If you want to run under .NET 4.0, you can do so, by adding requestValidationMode="2.0" to the <httpRuntime> tag in the web.config file as brought up here.  This is the simplest solution (or run under .NET 2.0).  I'm curious myself what .NET 4.0 is finding that .NET 2.0 didn't find, or wasn't looking at.

For the SQL error, you're not using a MembershipProvider section, right?  You could comment out the code in Add_entry.aspx that binds the users.  But you might need to put something in place of that.  When you save a Post, one property of the Post is "Author".  This value (Post.Author) comes from the dropdown list of authors.   This dropdown list is getting populated from Membership.GetAllUsers().  To be on the safe side, it's probably best that an Author name gets assigned to the Post (because Post.Author name is looked at in some places throughout the BE code).  So you could remove the dropdown list, comment out the call to BindUsers, and manually assign an author name to the Post.Author property in the function that takes care of Saving the post..  Maybe you would pick the name based on User.Identity.Name, for example.

Although you could put a dummy MembershipProvider section into the web.config file, it might be better that you leave it like it is so if there's other code that is reliant on Membership, you'll get a similar error when it tries to make a SQL connection.  This will tell you that that piece of code needs to be modified.  I'm not sure why SQL provider is being used when you don't have a MembershipProvider section.  It could be a machine default, like you suggest.

Aug 11, 2010 at 5:49 PM

Thanks for the reference article. I'll try that validation mode attribute at some point if necessary. I forwarded that to my friend too. I'd be curious about the validation of the form too. Let me know if you guys ever find out why.

Right. No Membership section in config. I didn't elaborate much, but that is what I did yesterday, comment out the Membership.whatever calls, and replace them with the best I could. For example, Author values are being filled with User.Identity.Name as you suggested... for the few other calls to Membership (associated with exporting author groups for a blog it seems) I left them commented out and un-replaced so that they will blow up when I use them and I can better discern how to handle the problem.

Things seem to be rolling pretty well so far though.


I marked "TODO" throughout the website wherever there was a call to IsAuthenticated or to AdministratorRole and such... and will customize that as we move forward with the development. For now it's up and running well enough to be a proof of concept as an addable feature to our intranet.


How soon are you guys shooting to release BE 2.0?

Aug 11, 2010 at 5:52 PM

Oh yeah, the SQL thing... the only thing I can think of, is much like the compilation attribute, maybe it is inheriting a Membership section from the parent site's web.config, or from Machine.config and causing it to attempt a connection. Not sure though. I'd really like to know that issue, as I said, it doesn't happen when hosted in VS.

Aug 11, 2010 at 6:13 PM

Ben - This is from a link on Hanselman's page you pointed me to; it's from the .Net 4.0 White Papers and may give you insight on where to begin looking for the request validation issue in BE.Net - I highlighted and changed colors the parts that caught my eye as I know they are used in BE and since the Page directive turned off validation, they make lots of sense as first places to look. Thanks for all your help once again Ben. You guys have an awesome product.

ASP.NET Request Validation

The request validation feature in ASP.NET provides a certain level of default protection against cross-site scripting (XSS) attacks. In previous versions of ASP.NET, request validation was enabled by default. However, it applied only to ASP.NET pages (.aspx files and their class files) and only when those pages were executing.

In ASP.NET 4, by default, request validation is enabled for all requests, because it is enabled before the BeginRequest phase of an HTTP request. As a result, request validation applies to requests for all ASP.NET resources, not just .aspx page requests. This includes requests such as Web service calls and custom HTTP handlers. Request validation is also active when custom HTTP modules are reading the contents of an HTTP request.

As a result, request validation errors might now occur for requests that previously did not trigger errors. To revert to the behavior of the ASP.NET 2.0 request validation feature, add the following setting in the Web.config file:

<httpRuntime requestValidationMode="2.0" />

However, we recommend that you analyze any request validation errors to determine whether existing handlers, modules, or other custom code accesses potentially unsafe HTTP inputs that could be XSS attack vectors.


My guess is it is one of your custom modules or handlers that is taking care of the post and does not explicitly have the validation turned off like the .ASPX page does. Good luck.

Oct 22, 2010 at 9:56 PM

Re: The most common security check in BE is to see if the user is either in the Administrators role, or to see if the person is logged in, either via:

-- or --


I just want to point out that these two properties aren't necessarily always one in the same. They generally start off the same during a request, but they can both be set to different values independently of one another. People should check for HttpContext.Current.User for ASP specific users. CurrentPrincipal can refer to plenty of other things(which is why it's used in WinForms and other non-web related .net projects).