Security :: Get Custom RoleProvider To Invoke Its Methods On Every Page Load
Jun 18, 2010
I had a post here [URL] that I need to expand on now. I have a few web pages that need to check for a certain role on each page request. I have a custom Membership Provider and a custom Role Provider (called CustomRoleProvider - very original - I know) that I am using to do this. When a user logs in, the CustomRoleProvider.GetRolesForUser() method is called automatically (by the urlAuthorizationModule). When this method gets called, I am currently adding a role to the roles string array that allows/permits the user from viewing the web pages of concern based on certain qualifications that are determined elsewhere in the code (i.e. the database is queried to see if the user has rights to visit certain pages).
This approach only gets me half way because the user's roles are only checked once at login. When I wrote my previous post, I thought the CustomRoleProvider was broken because it wasn't calling the IsUserInRole() method on each page request. According to Microsoft, "The IsUserInRole method is called by the IsUserInRole method of the Roles class to determine whether the current logged-on user is associated with a role from the data source for the configured ApplicationName." (that information comes from this page:
[URL] Reading that description I thought it was being called automatically on each page request. This is not correct. What I need to know how to do is to get a method in the CustomRoleProvider that returns a boolean to be called automatically on each page request so I can update the user's roles if they change while the user is logged into the web site. For example, if the user has rights to visit page A and then five minutes later his rights are revoked, he can't visit page A again unless he contacts an admin to reset his rights.
I have created a custom MembershipProvider and RoleProvider which communications with some existing business logic. The issue I have is that the user login in my business logic requires 3 arguments (group id, user id, and password) and the MembershipProvider and RoleProvider I implemented just use 1 or 2 arguments (username, password). Right now I append my group id and user id together and pass it as the username then parse it in the implemented methods. Is there a better way to do this?
Note, I can handle the login fine because I can call my own ValidateUser method. The main issue is when the implemented methods are called from other things like the RoleProvider.GetRolesForUser(username) method when I use the AuthorizeAttribute.
I am obviously missing something here and it is driving me batty. I am trying to implement a custom role provider so that I can add some of my own custom code to it. I have created my CustomRoleProvider class, I have inherited the RoleProvider base class and implemented its members. I have made the required changes to my web.config so that my CustomRoleProvider is used. This is all working great.
All of this is wrapped up in a wrapper class as provided by the MVC Membership Starter Kit that I am using and wish to extend.
Now I want to add my own custom functionality.
When I add a function to my CustomRoleProvider I cannot see it or access it.
How do I add functionality to my CustomRoleProvider so that I can use it?
I have written an assembly (DLL) containing two classes, MyMembershipProvider and MyRoleProvider, which are derived from MembershipProvider and RoleProvider, respectively. I have implemented most but not all of the abstract methods; the remaining ones all throw a NotImplementedException. I have signed the assembly and added a reference to it in my web-site project, where the relevant web.config sections look like this:
[Code]....
When I fire up the site, however, I get the following error:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Exception has been thrown by the target of an invocation.
The error message points to the <add /> tag in the <roleManager /> section: if I take that out, however (enabled="false"), it comes back again as soon as I try to log-in to the site (this time pointing to the membership section). I have verified that is recognising the classes by changing the name in the "type" attribute (to something that doesn't exist), at which point it throws a different error. Therefore I'm presuming there's a problem with my assembly code somewhere; but how can I find out where? I have debug=true in the web.config and also compiled the assembly with Debug options, but no clues.
On my local machine with the default ASP web server I am able to browse my web service's methods, which have with prompts and an invoke button.But when I deploy this same code to an IIS server and I browse the asmx page I just get a descritpion of the methods.
I have a web application that accesses a database through a wcf service. The idea is to abstract the data from the web application using the wcf service. All that works fine but I am also using the built in roleprovider using the SqlRoleManager which does access the aspnetdb database directly. I would like to abstract the roleprovider by creating a custom roleprovider in a wcf service and then accessing it through the wcf service.
I have created the custom role provider and it works fine but now I need to place it in a wcf service. So before I jump headlong into trying to get this to work through the WCF service, I created a second class in the web application that accessed the roleprovider class and changed my web config roleprovider parameters to use that class. So my roleprovider class is called, "UcfCstRoleProvider" and my web.config looks like this:
But I get this error."Provider must implement the class 'System.Web.Security.RoleProvider'."
I hope I have explained well enough to show what I am trying to do. If I can get the roleprovider to work through another class in the same application, I am sure it will work through the WCF service but how do I get past this error?Or maybe I took a wrong turn and there is a better way to do what I want to do??
public class TestRoles{ public class SimpleRoleProvider : RoleProvider { public override string[] GetRolesForUser(string username) { List<string> roles = new List<string>(); roles.Add("Guest"); if (username.Equals("Dave")) roles.Add("Admin"); return roles.ToArray(); } } }
From this error, it seems like it can't find the RoleProvider.
I have created custom membership and role providers for a SharePoint web application.
If I deploy the DLL for these classes into the GAC, the membership/role provision works just fine. If I deploy these DLLs to the web application's bin folder in IIS, the web app bails with a server error immediately when browsing to the site.
Parser Error Message: Exception has been thrown by the target of an invocation.
If I view source on the error page I get a bit more info:
I trying to understand how a server farm would use MembershipProvider / RoleProvider. If I have a million users, I do not want to have multiple copies of the MembershipProvider / RoleProvider database. I would like to have one set of machines used for login but then redirect users to other machines in the server farm depending applications the users decide to use. However, once they are redirected to the new machine, I do not want the user to have to relogin. I want the credentials and role information to be available.
Does anyone know how MembershipProvider / RoleProvider is configured for this type architecture?
Does Forms Authentication require that cookies be enabled to use MembershipProvider and RoleProvider? If so, can anyone tell me the minimum security level I need to tel clients to use.
Say for my ASP.NET application, I have implemented my custom RoleProvider by using my existing Users table on my Oracle 11g database. Then, for my Membership Provider, can I still use the AspNetSqlMembershipProvider that comes with the .NET framework and uses SQL Server?
I have to invoke SSIS packages from web service in the most secure way. I think that windows authentication will be secure but i am not sure. I do not have much knowledge about how to achieve this and the information on the internet is very distributed.
This is my first membership provider; I converted the sample provider [URL] to SQL. I created a vb class provider and put it into the App_Code folder. After it was created I tried to modify my webconfig but the error pops up. I don't know what else to try, I don't know if I have missed something
I am beginner in web applications development. I started one little project and host it on source forge "https://homoco.svn.sourceforge.net/svnroot/homoco". And I started implementing authentication in this application to learn how it works. From my experience people never use out of the box things so I want to implement this stuff alone (like in real world projects). So some questions:
1) Is there any reason to use membership out of the box? To use database table schema, stored procedures etc. that tool generate for developer. I think that this lower control over code and I decided to implement it my self. I don't know if I am right.
2) Is my approach in this demo project good or bad (if someone have time I like to do just a little code review)? I created database based on business rules. Not using database schema that membership provider require. Extend "MembershipProvider" class to satisfy my needs. Implement queries to database myself.
3) Now, this question is a little wired but I have to ask it. If we make custom Membership Provider and do sql queries alone, implement all MembershipProvider class methods ourselves, and in application use Membership.blabla() why is this approach different from not extending MembershipProvider class and putting all this methods in some unique class and call its methods then? I hope that someone understand what I ask here.
I am sorry for three questions, but I really trying to find the best way to implement this feature in my demo project like it is a real world application.
I have implemented role based security in my asp.net 2.0 vb.net application using windows authentication and the windowstokenroleprovider and limiting access to certain pages using the location tag to specific active directory groups.
The issue is that when a user tries to access a page they are not authorized to view it brings up a login prompt and when it does not pass it takes them to the default page that tells them they are not authorized to view the page. I am wondering if there is a way to throw up a custom page that tells them they are not athorized to view the page that I can incorporate into the site itself with the header and so forth? if this page could come up in lieu of the sign in box popping up as well.
I am getting an error with my custom RoleProvider (based on System.Web.Security.RoleProvider) initializing in my ASP.NET application. The error is: "Description: An error occurred during the processing of a configuration file required to service this request." I see this below error happening on a Windows 2003 server with .NET 3.5 SP1. I have not seen it on Windows 2008 servers, and have not seen the error when the ASP.NET application was built under .NET 2.0 (running on this same server). Any thoughts on the nature of the error?
Classification: UNCLASSIFIED
Caveats: NONE Server Error in '/Assist' Application. Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Line 122: <clear /> Line 123: <add Line 124: type="Grb.Security.FrameworkRoleProvider" Line 125: applicationName="MyApplication1" /> Line 126: </providers>
Source File: D:inetpubAssistweb.config Line: 124
Version Information: Microsoft .NET Framework Version:2.0.50727.3603; ASP.NET Version:2.0.50727.3082
HERE'S THE INITIALIZING FUNCTION FOR THE ROLE PROVIDER:
Public Overloads Overrides Sub Initialize(ByVal name As String, ByVal config As System.Collections.Specialized.NameValueCollection)
Try If config Is Nothing Then Throw New ArgumentNullException("config") End If If String.IsNullOrEmpty(name) Then name = Me.GetType().BaseType.Name End If If String.IsNullOrEmpty(config(DescriptionKey)) Then config.Remove(DescriptionKey) config.Add(DescriptionKey, SR.GetString(SR.RoleSqlProvider_description)) End If MyBase.Initialize(name, config) ' Get the configuration settings Dim configurationSettings1 As Grb.Framework.Business.ConfigurationSettings = Grb.Framework.Business.FrameworkConfiguration.GetConfiguration() ' Load the DomainManager
Dim dataManager1 As New Grb.Framework.Data.Main(Nothing, configurationSettings1.FrameworkSchema, configurationSettings1.AssistSchema, _ configurationSettings1.ConnectionString, configurationSettings1.ProviderInvariantName, _ configurationSettings1.EnablePerformanceLogging, System.Web.HttpContext.Current.Request.PhysicalApplicationPath) ' Load the DomainManager Dim frameworkDomainManager As Grb.Framework.Business.DomainManager = New Grb.Framework.Business.DomainManager(dataManager1, -1, -1) m_ProductDomainManager = New Grb.PlugIn.Assist.Business.DomainManager(dataManager1, frameworkDomainManager) m_ApplicationName = config(ApplicationNameKey) If String.IsNullOrEmpty(m_ApplicationName) Then m_ApplicationName = SecUtility.GetDefaultAppName() End If If m_ApplicationName.Length > 256 Then
Throw New System.Configuration.Provider.ProviderException(SR.GetString(SR.Provider_application_name_too_long))
End If config.Remove(ApplicationNameKey) If config.Count > 0 Then Dim attribUnrecognized As String = config.GetKey(0) If Not String.IsNullOrEmpty(attribUnrecognized) Then
Throw New System.Configuration.Provider.ProviderException(SR.GetString(SR.Provider_unrecognized_attribute, attribUnrecognized))
End If End If Catch ex As Exception Throw New Grb.Framework.Core.Exceptions.FrameworkBusinessException( _ Resources.ExceptionMessages.FrameworkRoleProvider_Initialize, ex) End Try End Sub
Set compilation debug="true" to insert debugging symbols into the compiled page. Because this affects performance, set this value to true only during development.
--> <compilation defaultLanguage="vb" debug="false"> <assemblies> </assemblies> </compilation> <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" /> <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </httpHandlers> <httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </httpModules> <!-- 1 GB maxRequestLength --> <httpRuntime maxRequestLength="1048576" /> <sessionState mode="InProc" timeout="60" /> <!-- note: Set authentication timeout >= session timeout (session timeout will clear authentication timeout upon session_start) --> <!-- note: <forms name="xxxx" value must be unique for each "forms authenticated" web application run on an IIS web server --> <!-- note: For a more secure system, set requiresSSL="true" (and install/setup an SSL key on the web site) --> <authentication mode="Forms"> <forms loginUrl="TimedOut.aspx" slidingExpiration="false" requireSSL="false" timeout="60"/> </authentication> <authorization> <deny users="?"/> <allow users="*"/> </authorization> <membership defaultProvider="FrameworkMembershipProvider1" userIsOnlineTimeWindow="15"> <providers> <clear /> <add name="FrameworkMembershipProvider1" type="Grb.Security.FrameworkMembershipProvider" applicationName="Product1" passwordRetrieval="false" passwordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="4" passwordStrengthRegularExpression="^[a-zA-Z0-9]+$" passwordStrengthFailedMessage="The password must be only alpha-numeric characters." frameworkDomainName="Master" maximumInvalidPasswordAttempts="3" maximumInvalidPasswordAttemptLockoutMinutes="30"/> </providers> </membership> <roleManager enabled="true" defaultProvider="FrameworkRoleProvider1"> <providers> <clear /> <add name="FrameworkRoleProvider1" type="Grb.Security.FrameworkRoleProvider" applicationName="MyApplication1" /> </providers> </roleManager> </system.web> <system.web.extensions> <scripting> <webServices> <!-- Uncomment this line to customize maxJsonLength and add a custom converter --> <!-- <jsonSerialization maxJsonLength="500"> <converters> <add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/> </converters> </jsonSerialization> --> <!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. --> <!-- <authenticationService enabled="true" requireSSL = "true|false"/> --> <!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and writeAccessProperties attributes. --> <!-- <profileService enabled="true" readAccessProperties="propertyname1,propertyname2" writeAccessProperties="propertyname1,propertyname2" /> --> </webServices> <!-- <scriptResourceHandler enableCompression="true" enableCaching="true" /> --> </scripting> </system.web.extensions> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules> <remove name="ScriptModule" /> <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </modules> <handlers> <remove name="WebServiceHandlerFactory-Integrated" /> <remove name="ScriptHandlerFactory" /> <remove name="ScriptHandlerFactoryAppServices" /> <remove name="ScriptResource" /> <remove name="WebServiceHandlerFactory-ISAPI-2.0"/> <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </handlers> </system.webServer> <location path="Default.aspx"> <system.web> <authorization> <allow users="*"/> </authorization> </system.web> </location> <location path="Portal.aspx"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="Login.aspx"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="PasswordChange.aspx"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="PasswordForgot.aspx"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <location path="PasswordEntry.aspx"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location> <!-- Give ControlLoader.aspx full access and let it check session/authentication validation.
The rational is that if a user is "timed-out" and presses a button to load a control into ControlLoader, the ControlLoader validation will catch this condition and tell the parent page to reload (so the Login page doesn't appear in the modal-dialog).
I have an ASP.NET application that P/Invokes a 32-bit DLL. When i deployed it on a 64-bit server i got the error "An attempt was made to load a program with an incorrect format". Then i configured IIS to run 32-bit as per instructions given here. Still get the same error.
I have a custom PagedDataSource created at page load.I have created two lin button "Next" and "Prev" to navigae the data source.I am using session to store the PDS and retrive it on each page load .I am incrementing CurrentPageIndex each time by 1 in the buttonNext click event and setting the value to the pds object.
What i am trying to do is, when the page loads, if page currently showing is last index, disable the "Next" button. The problem is, everytime I have to click "Next" one more time to make it disabled. It seems, the page does not recognize that it is the lastindex of the datasource when loading. When I click again one more time while in the last page , it is disabled.
I'm facing very odd problem with my application. I've been developing my own custom memberhip provider (derived from MembershipProvider, of course) and everything was working smoothly, until something odd happened. In my config file, I register my provider with such code:
[Code]....
When I deploy my site, I get this error message:
Configuration Error
Description:
An error occurred during the processing of a configuration file required to service this request. review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Input string was not in a correct format.
Source Error:
Line 62: <clear/> Line 63: <add name="CustomSqlMembershipProvider" Line 64: type="My_Membership.CustomSqlMembershipProvider" Line 65: applicationName="My Application" Line 66: enablePasswordRetrieval="false"