Professional ASP.NET 2.0 Security, Membership, and Role Management phần 10 potx

64 446 0
Professional ASP.NET 2.0 Security, Membership, and Role Management phần 10 potx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

You won’t encounter this behavior if you make authorization checks by calling IsUserInRole directly on the provider; when calling the provider’s IsUserInRole method directly you can use either syntax for local machine groups. However, if you depend on RolePrincipal.IsInRole for authorization checks you may run into this behavior and it may cause some unexpected problems. For example, using the TestLocalMachineGroup shown in the earlier results, the following URL authorization check when using Role Manager will fail: <authorization> <allow roles=”DEMOTEST\TestLocalMachineGroup”/> <deny users=”*”/> </authorization> This exact same check will succeed if you turn off Role Manager and just use Windows authentication instead. The WindowsPrincipal class never has to return roles as a string array, so when WindowsPrincipal.IsInRole is called, internally, it can test local machine groups using alternative syntaxes. The reason that the preceding check fails when using Role Manager is that RolePrincipal internally caches the string array returned by WindowsTokenRoleProvider.GetRolesForUser. And this array has only a string entry of TestLocalMachineGroup, so the string comparison against DEMOTEST\TestLocalMachineGroup fails. The following configuration though will succeed: <authorization> <allow roles=”TestLocalMachineGroup”/> <deny users=”*”/> </authorization> Now that the machine name is no longer part of the role name, the URL authorization check against RolePrincipal succeeds because there is a string match on just TestLocalMachineGroup. If you hap- pen to be developing an application, and authorization checks against local machine groups suddenly fail when you switch from using only Windows authentication to using Windows authentication and Role Manager with the WindowsTokenRoleProvider, the likely culprits are the group names in your <authorization /> configuration element. You can write some sample code that tries different ways of making role checks against the group names shown earlier that were returned from GetRolesForUser: Response.Write(“This Organization: “ + wp.IsUserInRole(User.Identity.Name, “This Organization”)); Response.Write(“This Organization: “ + wp.IsUserInRole(User.Identity.Name, “NT AUTHORITY\\This Organization”)); This code performs an authorization check against the “This Organization” default group. The first check does not include “NT AUTHORITY\\” in the roleName parameter, while the second role check does include it. This code results in the following output: This Organization: False This Organization: True Now clearly the user account belongs to this group, but in the first case, without “NT AUTHORITY\\” prepended to the roleName parameter, the group name was interpreted as a local machine group and thus the check failed. If you use a different well-known group that has been around for a while, you get different behavior: 549 Role Manager 16_596985 ch13.qxp 12/14/05 7:52 PM Page 549 Response.Write(“Local administrators: “ + wp.IsUserInRole(User.Identity.Name, “Administrators”) + “<br/>”); Response.Write(“Local administrators: “ + wp.IsUserInRole(User.Identity.Name, “BUILTIN\\Administrators”) + “<br/>”); This code uses two different variations for checking to see if the current user belongs to the local Administrators group. As you can see in the following output, both coding styles result in the same results: Local administrators: True Local administrators: True Because of the subtle differences in behavior when performing authorization checks with special group names, it is easier to always prepend either “NT AUTHORITY\\” or “BUILTIN\\”. For local machine groups, you can be more lax in your coding style when calling IsUserInRole, as the following code snippet demonstrates: Response.Write(“A local machine group: “ + wp.IsUserInRole(User.Identity.Name, “TestLocalMachineGroup”)); Response.Write(“A local machine group: “ + wp.IsUserInRole(User.Identity.Name, “DEMOTEST\\TestLocalMachineGroup”)); Both of these authorization checks will succeed: A local machine group: True A local machine group: True With either syntax for the roleName parameter, the provider interprets the roleName as a local machine group. For groups that you create in a domain, though, you must always prepend the group name with the domain name as the next sample demonstrates: Response.Write(“The domain Users group: “ + wp.IsUserInRole(User.Identity.Name, “CORSAIR\\Domain Users”)); Response.Write(“The domain Users group: “ + wp.IsUserInRole(User.Identity.Name, “Domain Users”)); The first call will succeed because the provider can successfully resolve this to the default “Domain Users” group that is present in every domain. However, the second check fails because the provider is looking for a group called “Domain Users” on the local machine. The domain Users group: True The domain Users group: False To summarize all of this, keep the following rules in mind when calling the provider’s IsUserInRole method: ❑ Always prepend “NT AUTHORITY\\” or “BUILTIN\\” when working with these types of groups. ❑ Always prepend “DOMAINNAME\\” when working with nonlocal groups located somewhere in a domain. 550 Chapter 13 16_596985 ch13.qxp 12/14/05 7:52 PM Page 550 ❑ Optionally, include “MACHINENAME\\” when working with local groups. See the following note, though. If you are using RolePrincipal.IsInRole to make authorization checks against local machine groups (either in your code or indirectly by using URL authorization), make sure to always leave off the machine name from any local groups. Summary The Role Manager feature gives you an easy way to create roles, assign users to roles, and then carry out various authorization checks based on these associations. As with the Membership feature, the Role Manager feature can be used to make authorization checks in both ASP.NET and non-ASP.NET environ- ments. The static Roles class is used for performing authorization checks if your application only has a single default provider, though for more complex sites you will probably end up getting references to specific RoleProvider instances directly instead. If your site uses multiple providers, you will probably also need to hook the GetRoles event on RoleManagerModule so that your RolePrincipal instances are associated with the proper provider. RoleManagerModule is the “magic” that exposes the user-to-role associations stored by providers as a RolePrincipal instance available from HttpContext.Current.User. You have to explicitly enable the Role Manager feature (it is off by default in machine.config) — but after you enable the feature RoleManagerModule automatically handles looking at the current user, and constructing a RolePrincipal that represents the current user. RolePrincipal can be used for declarative authoriza- tion checks such as URL authorization as well as code-based authorization checks using IPrincipal.IsInRole. Because Role Manager has no hard-coded dependencies on a specific type of authenticated identity, the RolePrincipal can wrap authenticated identities obtained from Windows authentication, forms authentication, or any custom authentication mechanism you may author. For performace reasons, RolePrincipal will fetch all of a user’s roles the first time the roles are needed, and it will then cache that information internally for the duration of a page request. You can optionally enable caching this information in a cookie so that on subsequent page requests RolePrincipal will initial- ize its cached role information from the cookie as opposed to calling the provider. The maxCachedResults configuration setting partially determines how many roles RolePrincipal is willing to stuff into a cookie. RoleManagerModule also enforces a maximum 4096 character limit on the size of a role cache cookie, so you will need to experiment with cookie caching in your applications to see if you can use it effectively. One of the default providers supplied with the Framework is WindowsTokenRoleProvider. This provider is very basic because it only implements the IsUserInRole and GetRolesForUser methods, and these methods only work with the currently authenticated user. However, the GetRolesForUser method can be very handy for developers who want to get all of the roles that a domain user belongs to. 551 Role Manager 16_596985 ch13.qxp 12/14/05 7:52 PM Page 551 16_596985 ch13.qxp 12/14/05 7:52 PM Page 552 SqlRoleProvider Role Manager ships with a number of different providers in the Framework: WindowsToken RoleProvider , which was covered at the end of the previous chapter; SqlRoleProvider, which is the topic of this chapter; and AuthorizationStoreRoleProvider, which is discussed in the next chapter. SqlRoleProvider is already configured in machine.config as the default provider for the Role Manager feature. As with SqlMembershipProvider, SqlRoleProvider is the reference provider for the feature because it implements all of the functionality defined on the RoleProvider base class. This chapter will cover the following areas of the SqlRoleProvider: ❑ The database schema used by the SqlRoleProvider ❑ Database security and trust level requirements for the provider, including how to configure the provider for use in partially trusted non-ASP.NET environments ❑ Using the SqlRoleProvider with Windows-authenticated websites ❑ Extending the provider to support “run-with-limited-roles” scenarios ❑ Leveraging role data for authorization checks in the data layer ❑ Supporting multiple applications with a single provider SqlRoleProvider Database Schema The database schema contains tables, views, and stored procedures used by the provider. As with the Membership feature, SqlRoleProvider’s schema integrates with the common set of tables covered in Chapter 11. This allows you to use SqlMembershipProvider for authentication and then use SqlRoleProvider to associate one or more roles with the users already registered in the Membership feature. Keying off of the common tables also allows SqlRoleProvider to be used in conjunction with the other SQL-based providers ( SqlProfileProvider and SqlPersonalizationProvider) 17_596985 ch14.qxp 12/14/05 7:54 PM Page 553 supplied by ASP.NET. However, there is no requirement that SqlRoleProvider be used on conjunction with the Membership feature. The integration with the common provider schema is nice if you want to leverage it, but you can also use Role Manager and SqlRoleProvider as a standalone authorization feature. You will actually see how this works later on in the chapter, where using SqlRoleProvider with Windows authentication is described. Because the concept of a role in Role Manager is very simple, and Role Manager also doesn’t support the concept of nested roles, the database tables for the SqlRoleProvider are also very simple. The first table in the database schema is the aspnet_Roles table shown in the following code: CREATE TABLE dbo.aspnet_Roles ( ApplicationId uniqueidentifier NOT NULL FOREIGN KEY REFERENCES dbo.aspnet_Applications(ApplicationId), RoleId uniqueidentifier PRIMARY KEY NONCLUSTERED DEFAULT NEWID(), RoleName nvarchar(256) NOT NULL, LoweredRoleName nvarchar(256) NOT NULL, Description nvarchar(256) ) Each of the table’s columns is described here: ❑ ApplicationId — Because multiple provider instances can be configured to point at the same database, you can horizontally partition each application’s role data using the applicationName configuration attribute supported in the provider’s configuration. In the database schema, this attribute’s value is translated to the GUID application ID that is stored in the common aspnet_Applications table. Whenever a SqlRoleProvider needs to look up role information, it always does so within the context of a specific application, and thus the provider always includes the ApplicationId column in the various stored procedures used by the provider. ❑ RoleId — The primary key for the table. Each role that is created using SqlRoleProvider is uniquely identified by its RoleId. Although the stored procedures perform most of their work using the RoleId, the public Role Manager API has no way to expose this value. As a result, the provider always starts its work with a role name. ❑ RoleName — For all practical purposes, this is the role “object” in the Role Manager feature. This is the value that you supply when creating new roles, and it is the value that you use when performing authorization checks with a RolePrincipal. ❑ LoweredRoleName —The case insensitive representation of the RoleName column. Although you write code using the value stored in the RoleName column, internally the SqlRoleProvider enforces the uniqueness of role names by first lowering the role string and then attempting to store it in this column. The combination of this column, and the ApplicationId column, acts as an alternate primary key for the table. Also, whenever you call the IsUserInRole method on the provider, the provider looks at the value in this column as part of determining whether a specific user is associated with a role. In this way, the provider is able to enforce case-insensitive string com- parisons on role names when performing role checks in the database. Note though that the culture setting (that is, collation order) of the underlying database still has an effect when the stored proce- dures are performing string comparisons. In the previous chapter, the potential mismatch between case-insensitive invariant-culture comparisons and case-insensitive culture-specific comparisons was discussed. You can always deploy the SqlRoleProvider schema in a database using the Latin1_General collation to roughly mirror the string comparison functionality used inside of RolePrincipal. 554 Chapter 14 17_596985 ch14.qxp 12/14/05 7:54 PM Page 554 ❑ Description — This is an orphan column because it is never used by the SqlRoleProvider. At one point, there were plans to make a full-fledged role object, but that work could not be fit into the ASP.NET 2.0 development schedule. Because ASP.NET may introduce a role object sometime in the future, the column was left in the schema for future use. You should basically ignore the existence of the column, and you should not store anything in it. The second table in the SqlRoleProvider database schema stores the mapping of users to roles: CREATE TABLE dbo.aspnet_UsersInRoles ( UserId uniqueidentifier NOT NULL PRIMARY KEY(UserId, RoleId) FOREIGN KEY REFERENCES dbo.aspnet_Users (UserId), RoleId uniqueidentifier NOT NULL FOREIGN KEY REFERENCES dbo.aspnet_Roles (RoleId) ) The aspnet_UsersInRoles table is ultimately used by various stored procedures to determine which users belong to which roles. The table works in a self-explanatory way; however, a brief description of each column is provided here. ❑ UserId — This is the user identifier from the common aspnet_Users table. For SqlRoleProvider to perform an authorization check, it must convert a string user name along with the application name specified on a provider, into a UserId value. Remember that the aspnet_Users table and aspnet_Applications tables together are used to accomplish this. ❑ RoleId — The role identifier from the aspnet_Roles table. During a database lookup, the string role name and the application name specified on a provider are converted into a RoleId. With the UserId and RoleId in hand, a stored procedure can perform a lookup in this table. In addition to the database tables, two views are supplied with the schema: vw_aspnet_Roles and vw_aspnet_UsersInRoles. Both of these views map all of the columns in the corresponding tables. Later on in this chapter, you will see how you can use these views to perform authorization checks inside of your own stored procedures. Also note that, as with the Membership feature, the views are intended only for use with read-only queries. Although nothing technically prevents you from writing data through the views, the intent is that all data modifications flow through the provider API. SQL Server–Specific Provider Configuration Options Because the SqlRoleProvider connects to SQL Server, it supports two SQL Server–specific configura- tion attributes on the provider definition: ❑ connectionStringName — As you would expect, the provider needs to know what database and server to connect to. The value of this attribute must point at a named connection string defined up in the <connectionStrings /> section. ❑ commandTimeout — As you work with larger databases, you may find that the default ADO.NET SqlCommand timeout of 30 seconds is too short for certain operations. For SqlRoleProvider, the AddUsersToRoles and RemoveUsersFromRoles methods are especially prone to timing out when working with large sets of role information (for example, the aspnet_UsersInRoles table contains 100K or more rows). If you run into timeout problems with either of these methods, you can boost the value of the commandTimeout configuration attribute to give the database server more time to complete its work. Alternatively, you can reduce the number of user-to-role associa- tions being modified in a single method call and simply call these methods in a loop with only a chunk of user and role data being changed in a single iteration. 555 SqlRoleProvider 17_596985 ch14.qxp 12/14/05 7:54 PM Page 555 Transaction Behavior Not all of the data modification work performed in the provider can be accomplished with single INSERT or UPDATE commands. The SqlRoleProvider methods AddUsersToRoles and RemoveUsersFromRoles both explicitly manage transactions within the provider’s code. If you look inside of the stored procedures used by SqlRoleProvider, you will see that for operations like deleting or creating a role, all the work is encapsulated within a transaction that is managed within a stored pro- cedure. However, the AddUsersToRoles and RemoveUsersFromRoles methods can affect many rows of user- to-role associations. As a result of limitations in passing parameter data down to a stored procedure, there isn’t a great way to get all of the parameter data from these methods (an array of users and an array of roles) passed down to SQL Server. The most elegant approach would have been to use the XML capability in SQL Server 2000, but this approach would have required forking the code to support SQL Server 7.0. There are also edge cases where errors can occur in stored procedures without being able to properly clear up XML documents that have been parsed on the server. So, the solution to the overall problem was to have SqlRoleProvider explicitly begin a transaction in the provider code. Then the provider passes chunks of user and role data down to SQL Server, poten- tially calling the underlying stored procedures multiple times. When all the parameter data has been chunked and passed to SQL Server, the provider issues an explicit COMMIT TRANSACTION to SQL Server. If anything fails along the way, all of the work is rolled back by the provider when it issues an explicit ROLLBACK TRANSACTION. You should keep this transaction behavior in mind when calling AddUsersToRoles and RemoveUsersFromRoles. If you pass a large number of users and roles these two methods can take quite a while to run, and there is the possibility of a failure occurring along the way thus causing a roll- back (just 100 users and 100 roles will result in 10K rows being inserted or deleted—so it doesn’t take much to trigger large numbers of inserts or deletes). If you want to smooth out the load on your SQL Server while performing large numbers of adds or removes, you should call these methods iteratively, passing only a small number of roles and users on each iteration. In this way, you eliminate the possibil- ity of SQL Server locking large portions of the aspnet_UsersInRoles table while it grinds through large data modifications. The product team has successfully tested performing 100K and 250K inserts and deletes using these methods. However, these tests were mainly to exercise the commandTimeout provider configuration attribute. Issuing such a huge number of changes in a single transaction ends up locking most of the aspnet_UsersInRoles table. In a production application, this type of change would potentially fail if the system was under load with other connections simultaneously attempting to get roles data from the same table. For this reason, limiting the number of associations being changed in any one method call to a small number makes sense for cases where the database needs to remain responsive to other applica- tions using the same set of Role Manager data. Provider Security There are two levels of security enforced by SqlRoleProvider: trust-level checks and database-level security requirements. You influence the trust-level check by setting the appropriate trust level for your web application and optionally making other adjustments to the CAS policy on your machine. Database- level security requirements are managed through the use of SQL Server roles. 556 Chapter 14 17_596985 ch14.qxp 12/14/05 7:54 PM Page 556 Trust-Level Requirements and Configuration Inside of the provider’s Initialize method a check is made for Low trust. If the current application is running at Low trust or higher, then the provider will initialize itself. Otherwise, if the application is running in Minimal trust, the initialization process will fail. Outside of ASP.NET, local applications like console applications or Winforms application implicitly run in Full trust, so the trust level check in the Initialize method always succeeds. For an ASP.NET application running in Low trust, the provider may still fail when you attempt to call any of its methods because the default Low trust policy file does not include SqlClientPermission. In this case, the Initialize method completes successfully because the Low trust-level check succeeds. But then when an individual method attempts to access SQL Server, the System.Data.SqlClient classes throw a security exception because the web application does not have SqlClientPermission. If you want to enable the provider for use in Low trust, you should do two things: 1. Create a custom trust policy file for the Low trust bucket, and add SqlClientPermission to the custom trust policy file. 2. Configure the database security for your application using one of the provider’s SQL Server roles. Because, conceptually, Low trust applications are not supposed to be modifying sensitive data, the aspnet_Roles_BasicAccess role makes sense for use with the SqlRoleProvider in a Low trust environment. Using Providers in Partially Trusted Non-ASP.NET Applications If you happen to run partially trusted non-ASP.NET applications, you don’t have the convenience of using the <trust /> configuration element. For example, if you run an application off of a UNC share, and you want that application to work with SqlRoleProvider (or for that matter, any other provider- based feature in ASP.NET, including the Membership and Profile features), you will initially end up with a rather obscure security exception. For example, you can create a basic console application that triggers initialization of the feature and the SqlRoleProvider with the following code: using System; using System.Web.Security; namespace PartialTrustRoleManager { class Program { static void Main(string[] args) { Console.WriteLine(Roles.Provider.ApplicationName); if (Roles.RoleExists(“some random role name”)) Console.WriteLine(“The random role exists.”); else Console.WriteLine(“The random role does not exist”); } } } 557 SqlRoleProvider 17_596985 ch14.qxp 12/14/05 7:54 PM Page 557 Because Role Manager is not enabled by default, the sample application also explicitly enables it in the application configuration file. <configuration> <system.web> <roleManager enabled=”true” /> </system.web> </configuration> If you compile this on your local machine and run it, everything works. However, if you take the com- piled executable and the configuration file, move them onto a remote UNC share, and then run the exe- cutable, you get the following exception. Unhandled Exception: System.Security.SecurityException: Request for the permission of type ‘System.Web.AspNetHostingPermission, ’ failed. <snipped for brevity> at PartialTrustRoleManager.Program.Main(String[] args) The action that failed was: LinkDemand The type of the first permission that failed was: System.Web.AspNetHostingPermission The first permission that failed was: <IPermission class=”System.Web.AspNetHostingPermission, ” version=”1” Level=”Minimal”/> Although the exception dump is a bit intimidating, hopefully parts of it look familiar to you from Chapter 3 on trust levels. In this situation, the executable is on a UNC share; it runs with a permission set defined by the Framework for applications running in LocalIntranet_Zone. You can see the zone membership and the permissions associated with it using the Microsoft .NET Framework 2.0 Configuration MMC. Note that this tool used to be available in the Administrative Tools menu in earlier builds of the 2.0 Framework. However you now have to install the Framework SDK and look for mscorcfg.msc in the SDK’s bin directory. The permission set associated with LocalIntranet_Zone is called LocalIntranet, and it includes only basic permissions like access to isolated storage, the use of default printers on the machine, and so forth. The LocalIntranet permission set lacks AspNetHostingPermission. It also lacks SqlClientPermission, although the previous exception dump doesn’t show this. The reason that the application immediately fails when run from a UNC share is that both the static Roles class and the SqlRoleProvider class are attributed with the following: [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] When the console application attempts to call into the Roles class, the declarative link demand immedi- ately causes a SecurityException because UNC based applications lack any kind of AspNetHostingPermission. Because a fair amount of work was invested in making the Membership, Role Manager and Profile fea- tures ASP.NET-agnostic, it would be unfortunate if these features were limited to only fully trusted non- ASP.NET applications. Luckily, this is not the case, although as you will see it does require configuration work on your part to get things working. Because there is no convenient code access security (CAS) 558 Chapter 14 17_596985 ch14.qxp 12/14/05 7:54 PM Page 558 [...]... following methods on SqlRoleProvider: IsUserInRole and GetRolesForUser These two methods represent the bare minimum needed to support the RolePrincipal object and authorization checks made directly against the provider ❑ aspnet_Roles_ReportingAccess — This role allows you to call IsUserInRole, GetRolesForUser, RoleExists, GetUsersInRole, FindUsersInRole, and GetAllRoles Members of this role can also issue... AddUsersToRoles — IAzRole::AddMemberName ❑ CreateRole — Either IAzApplication::CreateRole or IAzScope::CreateRole ❑ DeleteRole — Either IAzApplication::DeleteRole or IAzScope::DeleteRole ❑ FindUsersInRole — Not implemented ❑ GetAllRoles — Iterates through the roles returned by either the IAzApplization::Roles property or the IAzScope::Roles property ❑ GetRolesForUser — IAzClientContext::GetRoles ❑ GetUsersInRole... the method calls to the base SqlRoleProvider If you choose a subset of roles (choose only Role A and Role C), when the page refreshes, it reflects the restricted set of roles that the user belongs to Listbox contains: Role A Role C IsUserInRole checks: User is in Role A User is in Role C Now the user can only accomplish tasks on the site that are allowed to Role A and Role C Even though in the database... shows how to add a domain user to two roles stored in a SQL database with the SqlRoleProvider: 563 Chapter 14 if (!Roles.IsUserInRole(“CORSAIR\\demouser”, “Application Role A”)) Roles.AddUserToRole(“CORSAIR\\demouser”, “Application Role A”); if (!Roles.IsUserInRole(“CORSAIR\\demouser”, “Application Role C”)) Roles.AddUserToRole(“CORSAIR\\demouser”, “Application Role C”); Note how the username is supplied... currentRoleMembership = base.GetRolesForUser(username); string[] restrictedRoles = mu.Comment.Split(“;”.ToCharArray()); List confirmedRoles = new List(); foreach (string role in restrictedRoles) { if (Array.IndexOf(currentRoleMembership, role) != -1) confirmedRoles.Add (role) ; } return confirmedRoles.ToArray(); } else { return base.GetRolesForUser(username); } } Just as with the SqlRoleProvider, the... test user and set up some role associations For example, I created an account called “testuser” that belonged to three different roles After you log in, the information displayed on the page looks like: Listbox contains: Role A Role B Role C IsUserInRole User is in User is in User is in checks: Role A Role B Role C So far so good: the user belongs to all of the roles that you would expect, and currently... GetUsersInRole — IAzRole::MembersName ❑ IsUserInRole — Retrieves roles from IAzClientContext::GetRoles, and then performs a string comparison between the requested role and the set of roles returned from the AzMan method The comparison is case-insensitive and uses ordinal comparisons (that is, a caseinsensitive byte-by-byte string comparison using the invariant culture) ❑ ❑ 576 RemoveUsersFromRoles — IAzRole::DeleteMemberName... AuthorizationStoreRoleProvider After you have setup some roles and user-to -role assignments, you can dump out the roles that the user belongs to string[] roles = ((RolePrincipal)User).GetRoles(); foreach (string r in roles) Response.Write(User.Identity.Name + “ is in role “ + r + “”); This code snippet shows that the user account belongs to the Normal Users role: demouser98@corsair.com is in role Normal... (Roles.Provider.IsUserInRole(User.Identity.Name, Role B”)) sb.Append(“User is in Role B ”); if (Roles.Provider.IsUserInRole(User.Identity.Name, Role C”)) sb.Append(“User is in Role C ”); litIsInRoleTests.Text = sb.ToString(); Restricting a user to a subset of his or her available roles occurs when you click on the role restriction button protected void btnRestrictRole_Click(object sender,... != -1) 566 SqlRoleProvider && (base.IsUserInRole(username, roleName)) return true; else return false; ) } else { //No restriction is in effect return base.IsUserInRole(username, roleName); } } The IsUserInRole override follows the same general pattern as GetUserInRole The only difference is that in this case only a single role (the roleName parameter) is checked As with GetUserInRole the roleName parameter . provider. ❑ aspnet_Roles_ReportingAccess —This role allows you to call IsUserInRole, GetRolesForUser, RoleExists, GetUsersInRole, FindUsersInRole, and GetAllRoles. Members of this role can also. PRIMARY KEY(UserId, RoleId) FOREIGN KEY REFERENCES dbo.aspnet_Users (UserId), RoleId uniqueidentifier NOT NULL FOREIGN KEY REFERENCES dbo.aspnet_Roles (RoleId) ) The aspnet_UsersInRoles table is. possibility of a failure occurring along the way thus causing a roll- back (just 100 users and 100 roles will result in 10K rows being inserted or deleted—so it doesn’t take much to trigger large numbers

Ngày đăng: 12/08/2014, 23:22

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan