演练:在Silverlight Business应用程序中使用身份验证服务 Silverlight Business应用程序模板创建的解决方案自动允许身份验证(验证模式为Forms),角色和个性化功能。解决方案包含了数据表格来登录已经存在的用户和注册新用户。我们不用写额外的代码就可以使用这些特性。
演练:在Silverlight Business应用程序中使用身份验证服务Silverlight Business应用程序模板创建的解决方案自动允许身份验证(验证模式为Forms),角色和个性化功能。解决方案包含了数据表格来登录已经存在的用户和注册新用户。我们不用写额外的代码就可以使用这些特性。我们也可以通过定义角色、个性化属性来自定义解决方案。
在本演练中,我们将学习如何在Silverlight Business应用程序中使用身份验证、角色和个性化功能。我们将根据用户的凭证来限制对某些域操作的访问,并根据用户的偏好来定制用户界面。我们将使用ASP.NET网站管理工具来管理角色和用户。创建网站、用户、角色我们可以使用Silverlight Business应用程序模板提供的特性,来快速实施验证功能。在下面的章节,我们使用ASP.NET配置工具来创建用户和角色,并登陆此用户。我们还通过Silverlight Business应用程序提供的注册表格来注册新用户。1. 在Visual Studio中,选择"文件->新建->项目"."新建项目"对话框打开。2. 选择Silverlight项目类型。3. 选择Silverlight Business Application模板,并命名为ExampleBusinessApplication.4. 点击"OK".注意创建的项目结构。这个SL客户端项目中在Views文件夹中包含了SL页面。这些页面允许登陆用户和注册新用户。5. 打开ASP.NET 网站管理工具。(首先,在资源管理器中,选择服务端项目,然后打开ASP.NET配置工具。6. 在项目菜单中,选择ASP.NET Configuration.如果在项目菜单中,看不到ASP.NET Configuration选项,有可能是选择了客户端项目。7.在ASP.NET网站管理工具中选择"安全"标签。8. 在"角色"的部分,点击"创建或管理角色"链接。9. 添加一个名为Managers的角色,并点击"添加角色"按钮。10. 在右下角,点击"返回"按钮。11. 在“用户"的部分,点击"创建用户"按钮。12. 使用下面的值来创建新用户,并选择Managers角色复选框。- User Name : CustomerManager- Password : P@ssword- E-mail : someone@example.com- Security Question : Favorite color?- Security Answer : Blue- Managers role : selected13. 点击"创建用户"按钮。14. 关闭ASP.NET网站管理工具。15. 运行解决方案。应用程序的首页将会显示在web浏览器中。16. 在页面的右上角,点击”登陆"链接。登陆窗口将会出现。17. 为用户名称输入CustomerManager,为密码输入p@ssword,并点击"OK"按钮。现在我们就登陆这个用户了,注意到在页面右上角出现文本"Welcome CustomerManager"。18. 点击"登出"按钮。这时我们就不再以CustomerManager登陆了。下面的步骤,我们通过注册表格创建一个新用户。19. 再次点击"登陆"链接。20. 在登陆对话框中,点击"现在就注册"链接。注册表格就会出现了。21. 用下面的信息填充注册表。Username: SalesUserFriendly name: SalesUserEmail: someone@example.comPassword: P@sswordSecurity Question: What was the color of your first car?Security Answer: Green22. 点击"OK",创建一个新用户。注意,我们现在已经作为SalesUser登陆了。23. 关闭浏览器。24. 打开ASP.NET网站管理工具,点击"安全"标签。注意到已经有了两个用户和角色,即使我们只创建了一个角色。25. 点击“创建或管理角色”,注意到Managers和Registered Users角色。Registered User角色是Business应用程序模板自动生成的。26. 对"Registered Users",点击"管理"链接。注意,通过应用程序添加的名为SalesUser的用户已经在Registered Users角色中了。27. 关闭ASP.NET网站管理工具。定义访问权限和个性化属性我们通过为域服务应用RequiresAuthenticationAttribute和RequiresRoleAttribute属性,来限制对域服务的访问。如果域操作没有属性,对所有用户有效。在域操作上添加属性,并不能阻止用户调用域操作。只是没有所需凭证的用户会收到一个异常。根据角色限制显示数据1. 在资源管理器中,在服务端项目中,点击App_Data文件夹,选择"添加->已存在项"。2. 在"添加已存在项"对话框中,添加AdventureWorksLT示例数据库。3. 在服务端,添加一个新项,并选择ADO.NET Entity Data Model模板。4. 命名模型为AdventureWorksModel.edmx,并点击"添加"."实体数据模型向导"将会出现。5. 选择"从数据库生成"选项,并点击"下一步".6. 选择AdventureWorksLT数据库,并点击"下一步"。7. 从数据库对象列表中,选择Customer,Product,以及SalesOrderHeader表,然后点击"完成"。实体数据模型将会出现在设计器中。8. 生成解决方案。9. 在服务端,添加一个新项,并选择Domain Service Class模板。10. 命名为AdventureWorksDomainService,然后点击"添加"。11. 在"添加新域服务类"对话框中,选择Customer,Product和SalesOrderHeader实体。12. 点击"OK"以完成创建域服务。13. 在AdventureWorksDomainService类中,对GetSalesOrderHeader方法添加RequiresAuthenticationAttribute属性。 1 2 3 4 5 6 7 | [RequiresAuthentication()] public IQueryable<SALESORDERHEADER> GetSalesOrderHeaders() { return this .ObjectContext.SalesOrderHeaders; } |
1 2 3 4 5 6 7 | [RequiresRole( "Managers" )] public IQueryable<CUSTOMER> GetCustomers() { return this .ObjectContext.Customers; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [EnableClientAccess()] public class AdventureWorksDomainService : LinqToEntitiesDomainService<ADVENTUREWORKSLT_DATAENTITIES> { [RequiresRole( "Managers" )] public IQueryable<CUSTOMER> GetCustomers() { return this .ObjectContext.Customers; } public IQueryable<PRODUCT> GetProducts() { return this .ObjectContext.Products; } [RequiresAuthentication()] public IQueryable<SALESORDERHEADER> GetSalesOrderHeaders() { return this .ObjectContext.SalesOrderHeaders; } } |
1 2 3 4 5 6 7 8 | < PROFILE > < PROPERTIES > < ADD name = "FriendlyName" /> < ADD name = "DefaultRows" defaultValue = "10" type = "System.Int32" /> </ PROPERTIES > </ PROFILE > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | namespace ExampleBusinessApplication.Web { using System.Runtime.Serialization; using System.Web.Ria.ApplicationServices; public partial class User : UserBase { [DataMember] public string FriendlyName { get ; set ; } public int DefaultRows { get ; set ; } } } |
1 2 3 4 5 6 | < RECTANGLE x:Name = "Divider2" /> < HYPERLINKBUTTON x:Name = "Link3" NavigateUri = "/Reports" TargetName = "ContentFrame" Content = "{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}" /> |
1 2 3 4 5 6 7 8 9 10 11 | < SCROLLVIEWER x:Name = "PageScrollViewer" > < STACKPANEL x:Name = "ContentStackPanel" > < TEXTBLOCK x:Name = "HeaderText" Text = "{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}" /> < TEXTBLOCK x:Name = "ContentText" Text = "Display reports based on user permissions" /> </ STACKPANEL > </ SCROLLVIEWER > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | < NAVIGATION:PAGE <br x:Class = "ExampleBusinessApplication.Views.Reports" /> xmlns="" xmlns:x="" xmlns:d="" xmlns:mc="" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Reports Page" > < GRID x:Name = "LayoutRoot" > < SCROLLVIEWER x:Name = "PageScrollViewer" > < STACKPANEL x:Name = "ContentStackPanel" > < TEXTBLOCK x:Name = "HeaderText" Text = "{Binding Path=ApplicationStrings.ReportsPageTitle, Source={StaticResource ResourceWrapper}}" /> < TEXTBLOCK x:Name = "ContentText" Text = "Display reports based on user permissions" /> <? xml:namespace prefix = data ns = "" />< data:DataGrid Margin = "5" Name = "ProductsGrid" ></ data:DataGrid > < data:DataGrid Margin = "5" Name = "SalesOrdersGrid" ></ data:DataGrid > < data:DataGrid Margin = "5" Name = "CustomersGrid" ></ data:DataGrid > </ STACKPANEL > </ SCROLLVIEWER > </ GRID > </ NAVIGATION:PAGE > |
1 2 3 4 | private AdventureWorksDomainContext context = new AdventureWorksDomainContext(); int numberOfRows = 10; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private void LoadRestrictedReports() { LoadOperation<SALESORDERHEADER> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows)); SalesOrdersGrid.ItemsSource = loadSales.Entities; SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible; if (WebContext.Current.User.IsInRole( "Managers" )) { LoadOperation<CUSTOMER> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows)); CustomersGrid.ItemsSource = loadCustomers.Entities; CustomersGrid.Visibility = System.Windows.Visibility.Visible; } else { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private void LoadReports() { if (WebContext.Current.User.IsAuthenticated) { numberOfRows = WebContext.Current.User.DefaultRows; WebContext.Current.User.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged); LoadRestrictedReports(); } else { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed; } LoadOperation<PRODUCT> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows)); ProductsGrid.ItemsSource = loadProducts.Entities; } |
1 2 3 4 5 6 7 8 9 | void User_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "DefaultRows" ) { LoadReports(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 | void Authentication_LoggedIn( object sender, AuthenticationEventArgs e) { LoadReports(); } void Authentication_LoggedOut( object sender, AuthenticationEventArgs e) { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public Reports() { InitializeComponent(); this .Title = ApplicationStrings.ReportsPageTitle; WebContext.Current.Authentication.LoggedIn += new System.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedIn); WebContext.Current.Authentication.LoggedOut += new System.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedOut); LoadReports(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Windows.Navigation; using System.Windows.Ria; using System.Windows.Ria.ApplicationServices; using ExampleBusinessApplication.Web; using ExampleBusinessApplication.Resources; namespace ExampleBusinessApplication.Views { public partial class Reports : Page { private AdventureWorksDomainContext context = new AdventureWorksDomainContext(); int numberOfRows = 10; public Reports() { InitializeComponent(); this .Title = ApplicationStrings.ReportsPageTitle; WebContext.Current.Authentication.LoggedIn += new System.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedIn); WebContext.Current.Authentication.LoggedOut += new System.EventHandler<AUTHENTICATIONEVENTARGS>(Authentication_LoggedOut); LoadReports(); } private void LoadReports() { if (WebContext.Current.User.IsAuthenticated) { numberOfRows = WebContext.Current.User.DefaultRows; WebContext.Current.User.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(User_PropertyChanged); LoadRestrictedReports(); } else { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed; } LoadOperation<PRODUCT> loadProducts = context.Load(context.GetProductsQuery().Take(numberOfRows)); ProductsGrid.ItemsSource = loadProducts.Entities; } private void LoadRestrictedReports() { LoadOperation<SALESORDERHEADER> loadSales = context.Load(context.GetSalesOrderHeadersQuery().Take(numberOfRows)); SalesOrdersGrid.ItemsSource = loadSales.Entities; SalesOrdersGrid.Visibility = System.Windows.Visibility.Visible; if (WebContext.Current.User.IsInRole( "Managers" )) { LoadOperation<CUSTOMER> loadCustomers = context.Load(context.GetCustomersQuery().Take(numberOfRows)); CustomersGrid.ItemsSource = loadCustomers.Entities; CustomersGrid.Visibility = System.Windows.Visibility.Visible; } else { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; } } void Authentication_LoggedIn( object sender, AuthenticationEventArgs e) { LoadReports(); } void Authentication_LoggedOut( object sender, AuthenticationEventArgs e) { CustomersGrid.Visibility = System.Windows.Visibility.Collapsed; SalesOrdersGrid.Visibility = System.Windows.Visibility.Collapsed; } void User_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "DefaultRows" ) { LoadReports(); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | < STACKPANEL Grid.Row = "0" Orientation = "Horizontal" > < TEXTBLOCK Text = "Number of rows to display for reports: " ></ TEXTBLOCK > < COMBOBOX x:Name = "defaultRows" VerticalAlignment = "Top" Height = "20" > < COMBOBOXITEM Content = "1" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "2" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "3" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "4" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "5" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "6" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "7" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "8" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "9" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "10" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "15" ></ COMBOBOXITEM > < COMBOBOXITEM Content = "20" ></ COMBOBOXITEM > </ COMBOBOX > </ STACKPANEL > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public partial class ProfileWindow : ChildWindow { public ProfileWindow() { InitializeComponent(); string userDefaultRows = WebContext.Current.User.DefaultRows.ToString(); foreach (ComboBoxItem cbi in defaultRows.Items) { if (cbi.Content.ToString() == userDefaultRows) { defaultRows.SelectedItem = cbi; break ; } } } private void OKButton_Click( object sender, RoutedEventArgs e) { int newSelection = int .Parse(defaultRows.SelectionBoxItem.ToString()); if (newSelection != WebContext.Current.User.DefaultRows) { WebContext.Current.User.DefaultRows = newSelection; WebContext.Current.Authentication.SaveUser( true ); } this .DialogResult = true ; } private void CancelButton_Click( object sender, RoutedEventArgs e) { this .DialogResult = false ; } } |
1 2 3 4 | < BUTTON x:Name = "SettingsButton" Margin = "0,0,0,0" Content = "settings" Click = "SettingsButton_Click" ></ BUTTON > < TEXTBLOCK Text = " | " /> |
1 2 3 4 5 6 7 | private void SettingsButton_Click( object sender, RoutedEventArgs e) { ExampleBusinessApplication.Views.ProfileWindow settingsWindow = new ExampleBusinessApplication.Views.ProfileWindow(); settingsWindow.Show(); } |