User Simulation and authorization in WCF

Source: Internet
Author: User

Generally, some resources on the server (such as file systems and network sockets) need to be provided by the caller with a security password to determine whether the server has the right to access. The host process running the service is usually restricted to a certain range of permissions. In order to access those special resources, Impersonation is usually used to improve the service host process's permissions to meet the resource access requirements. In this case, the Service permission is improved. If the caller only needs a small permission, simulating the identity of the caller can reduce the Service permission to run. The simulation is to allow the host process running the service to replace the identity used by the current host process with the identity of the caller. Therefore, the service can only access the resources that the caller is allowed to access and run with the caller's permission. This can easily ensure that the user only accesses the appropriate data and resources. In WCF, you can set the simulation level through TokenImpersonationLevel.

TokenImpersonationLevel. None: There is no simulated level limit, and the client does not use Security creden.

TokenImpersonationLevel. Anonymous: the client does not use Security creden.

TokenImpersonationLevel. Identification: the server can identify the client, but the server cannot simulate the client. Everything the service does must be done with its own identity.

TokenImpersonationLevel. Impersonation: the server can identify the client and simulate the client.

Even if the service host is configured as an identity with low permissions, you can do anything that the client can do by simulating the client identity. The difference between a client and a service simulating its identity: when a service is not on the same machine as a client, it cannot access resources on another machine as a client, because the service simulation cannot really obtain the client password.

TokenImpersonationLevel. Delegation: Provides the client Kerberos ticket for the service. Services can freely access resources on any machine as clients do.

Write some simple code for testing. Before testing, you need to create a Test account named Test and password: wcf.

Service contract:

using System.ServiceModel;

namespace IFruitSvc
{
[ServiceContract(Namespace="http://www.cnblogs.com/qiuwuyu")]
public interface IFruitService
{
[OperationContract]
string GetFruitName();
}
}

Service implementation:

using System;
using IFruitSvc;
using System.ServiceModel;
using System.Security.Permissions;
using System.Security.Principal;
using System.Threading;

namespace FruitSvc
{
public class FruitService:IFruitService
{
[OperationBehavior(Impersonation = ImpersonationOption. Required)]
public string GetFruitName()
{
DisplaySecurityDetails();
return "banana";
}
private void DisplaySecurityDetails()
{
Console.WriteLine("Windows Identity:" + WindowsIdentity.GetCurrent().Name);
Console.WriteLine("Thread CurrentPrincipal Identity:" + Thread.CurrentPrincipal.Identity.Name);
Console.WriteLine("ServiceSecurityContext Current PrimaryIdentity:" +
ServiceSecurityContext.Current.PrimaryIdentity.Name);
Console.WriteLine("ServiceSecurityContext Current WindowsIdentity:" +
ServiceSecurityContext.Current.WindowsIdentity.Name);
}
}
}

Storage Service:

using System;
using IFruitSvc;
using FruitSvc;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WcfSecurityHost
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(FruitService),
new Uri("net.tcp://localhost:8000")))
{
host.AddServiceEndpoint(typeof(IFruitService), new NetTcpBinding(), "FruitService");

host.Authorization.ImpersonateCallerForAllOperations = true;
host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseWindowsGroups;

host.Open();
Console.WriteLine("Fruit Service Is Running...");
Console.ReadLine();
}
}
}
}

Client call:

using System;
using System.ServiceModel;
using IFruitSvc;

namespace WcfSecurityClient
{
class Program
{
static void Main(string[] args)
{
EndpointAddress epAddr = new EndpointAddress("net.tcp://localhost:8000/FruitService");
ChannelFactory<IFruitService> factory = new ChannelFactory<IFruitService>(new NetTcpBinding(), epAddr);
factory.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Identification;
IFruitService proxy = factory.CreateChannel();

Console.WriteLine(proxy.GetFruitName());

Console.ReadLine();
}
}
}

The running result is as follows:

Modify the client code so that the service can run as a Test user and add a line of code.

// LiFeng computer name in "LiFeng \ Test". The Test user name allows the service to run as "LiFeng \ Test"
Factory. Credentials. Windows. ClientCredential = new System. Net. NetworkCredential (@ "LiFeng \ Test", "wcf ");

The execution result is as follows:

It can be seen that the Service Running uses the identity of the Test user.

The resources required for using the simulation will increase with the increase of the client, which will not benefit from the resource pool (such as the connection pool), but also increase the complexity of resource management, A large number of identities need to be managed due to the need to grant resource access permissions to the initial client identity. If a service always runs as a visitor, the preceding problems do not exist. Therefore, authorization should be used for resource access control.

Next, modify the code and perform some simple tests. Use the code to understand authorization.

Use [PrincipalPermission (SecurityAction. Demand, Name =
@ "LiFeng \ Administrator")] modifies the GetFruitName () method in the FruitService class. That is to say, authorize the call of this method to the user whose computer name is LiFeng and whose username is Administrator. Other users are not authorized to access this method.

Running the program will throw "Request for principal permission failed." because the account "LiFeng \ Test" is still used, it has no access permission. Change to [PrincipalPermission (SecurityAction. Demand, Name =
@ "LiFeng \ Test")] the program will run normally. It is only for testing. If authorization is used in the program, it is best to authorize the role instead of authorizing every user.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.