饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 108 页

作者:Nick Randolph/等 当前章节:15404 字 更新时间:2026-6-18 14:51

Code snippet MainWindow.cs

728 .

chaPter 33 clienT ApplicATion SerViceS

Vb

Imports System.Web.Security

Class MainWindow

Private Sub Window_Loaded(ByVal sender As System.Object,

yVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

If Membership.ValidateUser(Nothing, Nothing) Then

MessageBox.Show("User is valid")

Else

MessageBox.Show("Unable to verify user, application exiting")

Me.Close()

Return

End If

End Sub

End Class

Code snippet MainWindow.vb

Interestingly, there is no overload of the ValidateUser method that accepts no arguments;

instead, when using Windows authentication, you should use Nothing (VB) or null (C#) for the

username and password arguments. In this case, ValidateUser does little more than prime the

CurrentPrincipal of the application to use the client application services to determine which

roles the user belongs to, and by default will return true. You see later that using this method is the

equivalent of logging the user in to the application.

The preceding code snippet, and others throughout this chapter, may require you

to import the System.Web.Security namespace into this class file. You may

also need to manually add a reference to System.Web.dll in order to resolve

type references.

The client application services include what is

often referred to as an application framework

for handling security. VB has for a long

time had its own application framework for

Windows Forms Applications that is enabled

and disabled via the Application tab on the

project properties designer. This framework

already includes limited support for handling

user authentication, but it conflicts with the

client application services. Figure 33-2 shows

how you can elect to use an application-

defined authentication mode so that you can

use both the Windows application framework and the client application services in your application.

Note that this setting is available only if you are developing a Windows Forms Application in VB.

fiGure 33-2

role authorization .

729

role authorization

So far, you have seen how to enable the client application services, but they haven’t really started to

add value because the user was already authenticated by the operating system when you were using

Windows authentication for the client application. What isn’t handled by the operating system is

specifying which roles a user belongs to and thus what parts or functions within an application the

user can access. Although this could be handled by the client application itself, it would be difficult to

account for all permutations of users and the system would be impractical to manage, because every time

a user was added or changed roles a new version of the application would have to be deployed. Instead,

it is preferable to have the correlations between users and roles managed on the server, allowing the

application to work with a much smaller set of roles through which to control access to functionality.

The true power of the client application services becomes apparent when you combine the client-side

application framework with the ASP.NET Application Services. To see this, you should add a new

project to your solution using the (VB or C#) ASP.NET Empty Web Application template (under the

Web node in the New Project dialog), calling it ApplicationServices.

Right-click the newly created project in Solution Explorer and select Properties to bring up the

project properties designer. Because you will be referencing this web application from other parts

of the solution, it is preferable to use a predefined port and virtual directory with the Visual

Studio Development Server. On the Web tab, set the specific port to 12345 and the virtual path to

/ApplicationServices.

ASP.NET Application Services is a provider-based model for authenticating users, managing

roles, and storing profile (a.k.a. settings) information. Each of these components can be engaged

independently, and you can either elect to use the built-in providers or create your own. To enable

the role management service for access via client application services, add the following snippet

before the <system.web> element in the web.config file in the ApplicationServices project:

<system.web.extensions>

<scripting>

<webServices>

<roleService enabled="true"/>

</webServices>

</scripting>

</system.web.extensions>

Code snippet web.config

Because you want to perform some custom logic to determine which roles a user belongs to,

you will need to create a custom role provider, called CustomRoles, to take the place of the

default role provider. This is done by adding a new class to your project and implementing

the RoleProvider abstract class. For this role provider, you are interested only in returning a value

for the GetRolesForUser method; all other methods can be left as method stubs.

c#

public class CustomRoles: RoleProvider{

public override string[] GetRolesForUser(string username){

if (username.ToLower().Contains("nick")){

return new string[] { "All Nicks" };

730 .

chaPter 33 clienT ApplicATion SerViceS

}

else{

return new string[] { };

}

}

Code snippet CustomRoles.cs

Vb

Public Class CustomRoles

Inherits RoleProvider

Public Overrides Function GetRolesForUser(ByVal username As String) As String()

If username.ToLower.Contains("nick") Then

Return New String() {"All Nicks"}

Else

Return New String() {}

End If

End Function

Code snippet CustomRoles.vb

You now have a custom role provider and have enabled role management. The only thing missing is

the glue that lets the role management service know to use your role provider. You provide this by

adding the following roleManager node to the <system.web> element in the web.config file:

<roleManager enabled="true" defaultProvider="CustomRoles">

<providers>

<add name=" CustomRoles" type="AuthenticationServices.CustomRoles"/>

</providers>

</roleManager>

Code snippet web.config

The last thing to do is to make use of this role information in your application. You do this by first

configuring your application with the URI to use for loading role information. On the Services tab

of the ClientServices project properties (shown in Figure 33-1), enter http://localhost:12345/

ApplicationServices. Next, you need to add a call to IsUserInRole to the Window_Loaded method:

c#

private void Window_Loaded(object sender, RoutedEventArgs e){

if (Membership.ValidateUser(null, null))

{ // Commented out for brevity.

}

if (Roles.IsUserInRole("All Nicks")){

MessageBox.Show("User is a Nick, so should have Admin rights.");

}

}

Code snippet MainWindow.cs

User authentication .

731

Vb

Private Sub Window_Loaded(ByVal sender As System.Object,

ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

If Membership.ValidateUser(Nothing, Nothing) Then

'. Commented out for brevity .

End If

If Roles.IsUserInRole("All Nicks") Then

MessageBox.Show("User is a Nick, so should have Admin rights.")

End If

End Sub

Code snippet MainWindow.vb

To see your custom role provider in action, set a breakpoint in the GetRolesForUser method.

For this breakpoint to be hit, you have to have both the client application and the web application

running in debug mode. To do this, right-click the Solution node in the Solution Explorer

window and select Properties. From the Startup Project node, select Multiple Startup Projects

and set the action of both projects to start. Now when you run the solution, you will see that the

GetRolesForUser method is called with the Windows credentials of the current user, as part of the

validation of the user.

user authentication

In some organizations it would be possible to use Windows authentication for all user validation.

Unfortunately, in many cases this is not possible, and application developers have to come up with

their own solutions for determining which users should be able to access a system. This process

is loosely referred to as forms-based authentication, because it typically requires the provision

of a username and password combination via a login form of some description. Both ASP.NET

Application Services and the client application services support forms-based authentication as an

alternative to Windows authentication.

To begin with, you will need to enable the membership management service for access by the

client application services. Adding the <authenticationService> element to the <system

.web.extensions> element in the web.config file does this. Note that we have disabled the

SSL requirement, which is clearly against all security best practices and not recommended for

production systems.

<system.web.extensions>

<scripting>

<webServices>

<authenticationService enabled="true" requireSSL="false"/>

<roleService enabled="true"/>

Code snippet web.config

The next step is to create a custom membership provider that will determine whether a specific

username and password combination is valid for the application. To do this, add a new class,

CustomAuthentication, to the ApplicationServices application and set it to inherit from the

732 .

chaPter 33 clienT ApplicATion SerViceS

MembershipProvider class. As with the role provider you created earlier, you are just going to

provide a minimal implementation that validates credentials by ensuring the password is the reverse

of the supplied username, and that the username is in a predefined list.

c#

public class CustomAuthentication : MembershipProvider{

private string[] mValidUsers = { "Nick" };

public override bool ValidateUser(string username, string password)

{

var reversed = new string(password.Reverse().ToArray());

return (from user in mValidUsers

where string.Compare(user, username, true) == 0 &&

user == reversed

select user).Count() > 0;

}

// The rest of the implementation has been omitted for brevity

}

Code snippet CustomAuthentication.cs

Vb

Public Class CustomAuthentication

Inherits MembershipProvider

Private mValidUsers As String() = {"Nick"}

Public Overrides Function ValidateUser(ByVal username As String,

ByVal password As String) As Boolean

Dim reversed As String = New String(password.Reverse.ToArray)

Return (From user In mValidUsers

Where String.Compare(user, username, True) = 0 And

user = reversed).Count > 0

End

'The rest of the implementation has been omitted for brevity

End Class

Code snippet CustomAuthentication.vb

As with the role provider you created, you will also need to inform the membership management

system that it should use the membership provider you have created. You do this by adding the

following snippet to the <system.web> element in the web.config file:

<membership defaultProvider="CustomAuthentication">

<providers>

<add name="CustomAuthentication"

type="ApplicationServices.CustomAuthentication"/>

</providers>

</membership>

<authentication mode="Forms"/>

Code snippet web.config

settings .

733

Back on the client application, only minimal changes are required to take advantage of the changes

to the authentication system. On the Services tab of the project properties designer, select Use Forms

Authentication. This enables both the Authentication Service Location textbox and the Optional:

Credentials Provider textbox. For the time being, just specify the authentication service location as

http://localhost:12345/ApplicationServices.

Previously, using Windows authentication, you performed the call to ValidateUser to initiate the

client application services by supplying Nothing as each of the two arguments. You did this because

the user credentials could be automatically determined from the current user context in which the

application was running. Unfortunately, this is not possible for Forms authentication, so you need to

supply a username and password:

c#

private void Window_Loaded(object sender, RoutedEventArgs e){

if (Membership.ValidateUser("Nick", "kciN")){

MessageBox.Show("User is valid");

Code snippet MainWindow.cs

Vb

Private Sub Window_Loaded(ByVal sender As System.Object,

ByVal e As System.Windows.RoutedEventArgs) _

Handles Me.Loaded

If Membership.ValidateUser("Nick", "kciN") Then

MessageBox.Show("User is valid")

Code snippet MainWindow.vb

If you specify a breakpoint in the ValidateUser method in the ApplicationServices project, you will

see that when you run this solution the server is contacted in order to validate the user. You see later

that this information can then be cached locally to facilitate offline user validation.

settinGs

In the .NET Framework v2.0, the concept of settings with a User scope was introduced to allow

per-user information to be stored between application sessions. For example, window positioning

or theme information might have been stored as a user setting. Unfortunately, there was no way to

centrally manage this information. Meanwhile, ASP.NET Application Services had the notion of

profile information, which was essentially per-user information, tracked on a server, that could be

used by web applications. Naturally, with the introduction of the client application services, it made

sense to combine these ideas to allow settings to be saved via the Web. These settings have a scope

of User (Web).

As with the membership and role services, you need to enable the profile service for access by the

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页