Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



LearnNow


XAMALOT
 


SSWUG


Reader rating:
Click here to read 45 comments about this article.
Article source: CoDe (2006 - Nov/Dec)


Article Pages: < Previous - 1 2 3  4  5 6 - Next >


Fundamentals of WCF Security (Cont.)

Role-Based Authorization

Despite the importance and granularity of the claims-based authorization model in WCF, role-based security is still alive and well, and is useful for controlling access to service operations and business classes used downstream. This type of authorization is based on the security principal for the request.

"
“The identity model in WCF supports a rich, claims-based approach to authorization.”
"

The identity of the caller is attached to the executing request thread in the form of a security principal, accessible through the CurrentPrincipal property.

System.Threading.Thread.CurrentPrincipal

The security principal is a wrapper for an identity-its type directly related to the token type received. For example, it could be a WindowsIdentity, X509Identity, GenericIdentity, or a custom type that implements System.Security.Principal.IIdentity. The identity is created during authentication as I discussed.

The actual security principal is a type that implements System.Security.Principal.IPrincipal. This interface has two members:

  • A read-only Identity property that returns a reference to the IIdentity for the request.
  • An IsInRole() method that returns a true or false result after checking to see if the identity is in a particular role.

The choice of role provider for a request influences the type of security principal attached to the thread. Options for role provider include:

None. No role provider.

Windows. Use Windows roles and add a WindowsPrincipal to the security context.

UseAspNetProvider. Use the configured RoleProvider type, which defaults to the ASP.NET role provider. This adds a RoleProviderPrincipal to the security context.

Custom. Relies on a custom authorization policy to add a security principal to the security context.

The default role provider is “Windows” therefore a WindowsPrincipal is the default type. For Windows, UserName or Certificate credentials (when Certificates are mapped to Windows accounts) this will contain an authenticated WindowsPrincipal, otherwise the principal is unauthenticated and has no runtime use for role-based security.

If you aren’t expecting Windows credentials, you can change the role provider by setting the principalPermissionMode value of the <serviceAuthorization> behavior (Listing 1). If you are using the ASP.NET credentials database, you can set it to “UseAspNetProvider”. This causes a RoleProviderPrincipal to be attached to the thread instead of a WindowsPrincipal. This IPrincipal type is new to WCF, and holds a reference to the ServiceSecurityContext. When the identity is requested from the principal, it actually returns a reference to the ServiceSecurityContext’s PrimaryIdentity property (discussed earlier). When IsInRole() is invoked, it uses the configured RoleProvider (in this case, the default ASP.NET role provider) to check if this identity is in the specified role.

You can also customize this behavior with a custom ASP.NET RoleProvider or with a custom authorization policy.

In any case, .NET role-based security relies on the IPrincipal object attached to the thread to perform authorization checks. So, even with WCF you can use the PrincipalPermission type to demand things like:

  • Is the user authenticated?
  • Is the user in a particular role?
  • Is a particular user calling?

At runtime, this can be done with an imperative permission demand within the WCF operation or any business component. Just create a PrincipalPermission object, initialize the values you want to enforce, and issue the Demand().

public string AdminsOnly()
{
  // unprotected code

  PrincipalPermission p = new 
PrincipalPermission(null, "Administrators");
  p.Demand();
  
  // protected code
}

In this example, an exception will be thrown if the user is not in the Administrators group.

You can also place a declarative PrincipalPermissionAttribute on any WCF operation or business component method to apply the demand before the operation or method is invoked:

[PrincipalPermission(SecurityAction.Demand, Role =
"Administrators")]
public string AdminsOnly()
{
  // protected code
}

This approach is preferable since it decouples the security requirements from the actual code within the operation.

In both scenarios, the IsAuthenticated property of the identity is verified, and the IsInRole() method is invoked to check membership using the IPrincipal object attached to the thread.

Custom Authorization Policies

Credential authentication, default claimset generation, and access to the security principal for role-based demands are all features that are configurable as I’ve discussed so far in this section. These are features that you get “for free”, with little extra coding effort.

I also mentioned earlier that you can create custom authorization policies for your WCF services. These are types that implement the IAuthorizationPolicy interface from the System.IdentityModel.Policy namespace. Here are a few useful reasons to create a custom authorization policy:

  • When the service requires SAML tokens as the client credential type the claims are not authenticated against any existing role provider. A custom authorization policy can inspect these claims and initialize the security context accordingly.
  • A service may replace traditional role-based security with claims-based security. An authorization policy can be used to normalize the set of claims received from different tokens into a common set of claims used for claims-based security.
  • Services that use a custom role provider must provide an authorization policy to create an IPrincipal for the security context. Without it, authorization will fail.

The code sample for this article includes an advanced sample that illustrates an IAuthorizationPolicy implementation.

Impersonation

With all this talk about authentication and authorization, impersonation is worth discussing. When Windows credentials are used, the service can be configured to impersonate callers so that the request thread operates under the impersonated Windows token. This makes it possible for services to access protected Windows resources under the identity of the caller, instead of the process identity of the service-for that request.

Using the OperationBehaviorAttribute you can apply impersonation rules per operation by setting the Impersonation property to one of the following:

  • ImpersonationOption.NotAllowed. The caller will not be impersonated.
  • ImpersonationOption.Allowed. The caller will be impersonated if a Windows credential is provided.
  • ImpersonationOption.Required. The caller will be impersonated and a Windows credential must be provided to support this.

This behavior is applied to service operations.

[OperationBehavior(Impersonation = 
ImpersonationOption.Allowed)]
public string DoSomething()
{
  ...
}

You can also set this for all operations by declaratively configuring the impersonateCallerForAllOperations attribute for the service authorization behavior.

<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehavior">
      <serviceAuthorization 
impersonateCallerForAllOperations="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Clients can also control impersonation, to prevent services from using their identity to access resources. Windows credentials have an AllowedImpersonationLevel property that can be set to one of the following:

  • TokenImpersonationLevel.None
  • TokenImpersonationLevel.Anonymous
  • TokenImpersonationLevel.Identification
  • TokenImpersonationLevel.Impersonate
  • TokenImpersonationLevel.Delegate

None and Anonymous protect the caller’s identity but aren’t useful for authentication. Identify is the default and preferred setting since it allows services to identify the caller but disallows impersonation. Impersonate and Delegate will allow impersonation across one machine, or delegation with a Kerberos ticket, respectively.

You set the value on the proxy as follows:

localhost.HelloIndigoServiceClient proxy = new 
Client.localhost.HelloIndigoServiceClient();
…                
proxy.ClientCredentials.Windows.
AllowedImpersonationLevel = 
TokenImpersonationLevel.Identification;
&


Article Pages: < Previous - 1 2 3  4  5 6 - Next Page: 'Applied WCF Security' >>

Page 1: Fundamentals of WCF Security
Page 2: Security Mode
Page 3: Authentication, Authorization, and Identities
Page 4: Role-Based Authorization
Page 5: Applied WCF Security
Page 6: Business Partner Applications

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
3.4 out of 5

278 people have rated this article.

Instantly Search Terabytes Of Text
“Lightning Fast”
– Redmond Mag
“Covers all data
sources” – eWeek
25+ fielded & full-text search options
dtSearch’s own document filters highlight hits in popular file types
Web Spider supports static & dynamic data
APIs for .NET, Java, C++, SQL, etc.
Win / Linux (64-bit & 32-bit)
www.dtSearch.com
 

      LearnNow

 

SSWUG