close

Вход

Забыли?

вход по аккаунту

код для вставкиСкачать
DEV354
Distributed Security
Practices
Juval Löwy
www.idesign.net
About Juval Löwy
Software architect
Consults and trains on .NET migration and design
MS Regional Director for the Silicon Valley
Authored
Programming .NET components (2003, O’Reilly)
COM and .NET component services (2001, O’Reilly)
Participates in the .NET design reviews
Contributing editor and columnist to the Visual
Studio Magazine
Contact at www.idesign.net
Outline
.NET role-based security
Web services security
.NET remoting and security
Enterprise Services security
Design guidelines and example
(time permitting)
.NET Role-Based Security
©2003 IDesign Inc. All rights reserved
Role-Based Security
User, instead of code permission
What a particular security identity is
allowed to do
Identity is user or account
Authorize based on identity
Roles are by default NT user groups
Can define with some work other options
Role-Based Security
Declare in code required role memberships
[PrincipalPermission(SecurityAction.Demand,Role=@"<domain>\Manager")]
public class MyClass
{}
Can apply on methods, but not interfaces
Must set the principal policy first per app domain
Typically done in Main()
static void Main()
{
AppDomain currentDomain = Thread.GetDomain();
currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
}
Role-Based Security
Can demand a particular user (with or
without role):
[PrincipalPermission(SecurityAction.Demand,
Role =@"<domain>\Manager",
Name ="Bill")]
public class MyClass
{}
Can demand only that user is
authenticated:
[PrincipalPermission(SecurityAction.Demand,Authenticated=true)]
public class MyClass
{}
Principal
Principal implements IPrincipal
System.Security.Principal
public interface IPrincipal
{
IIdentity Identity {get;}
bool IsInRole(string role);
}
An object representing identity and role(s)
information
Everything you need to know to make
authorization decision
Principal
Every thread has a principal
Available implementations
GenericPrincipal
WindowsPrincipal
Programmatic RBS
When decision requires runtime parameters
[PrincipalPermission(SecurityAction.Demand,Role =@"<domain>\Customers")]
[PrincipalPermission(SecurityAction.Demand,Role =@"<domain>\Tellers")]
public void TransferMoney(double sum,long accountSrc,long accountDest)
{
IPrincipal principal;
principal = Thread.CurrentPrincipal;
bool callerInRole = false;
callerInRole = principal.IsInRole(@"<domain>\Customer");
if(callerInRole)//The caller is a customer
{
if(sum > 5000)
{
string msg = @"Caller does not have sufficient credentials to
transfer this sum";
throw(new UnauthorizedAccessException(msg));
}
}
DoTransfer(sum,accountSrc,accountDest);//Helper method
}
Web Services Security
©2003 IDesign Inc. All rights reserved
Security
Based on IIS/ASP.NET
No user/UI pages/forms
Client must set credentials programmatically
Windows authentication
Basic, Digest, Integrated
Client has Windows account on server
Set authentication to Windows in config
file
All calls are authenticated
Security
Custom
Granular control
Must enable anonymous access
Set authentication to None in config file
Various options
Logon method with cookie
SOAP header
SOAP extension
Windows Authentication Basic
Client provides credentials
Set Credentials property of wrapper class
ICredentials
null by default
Available implementations
NetworkCredentials,CredentialCache
Provide domain, user name and password
Can enable pre-authentication
Windows Authentication Basic
Client sets credentials dynamically
using System.Net;
SecureCalculator calc = new SecureCalculator();
ICredentials credentials;
credentials = new NetworkCredential("UserName","Password","Domain");
calc.Credentials = credentials;
calc.PreAuthenticate = true; //Optional
int res = calc.Add(2,3);
Debug.Assert(res == 5);
Client may not be a Windows station
Windows Authentication Basic
Can encapsulate in constructor of
proxy class if credentials are static
using System.Net;
public class SecureCalculator : SoapHttpClientProtocol
{
public SecureCalculator ()
{
ICredentials creds;
creds = new NetworkCredential("UserName","Password","Domain");
Credentials = creds;
Url = "http://www.CalculationServices/SecureCalculator.asmx";
}
//Method wrappers…
}
Windows Authentication Digest
Send hash of password
IIS verifies password
Requires Active Directory
Client may not be a Windows station
SecureCalculator calc = new SecureCalculator();
ICredentials credentials = new CredentialCache();
Uri uriPrefix = new Uri(@"http://www.CalculationServices/");
ICredentials creds;
creds = new NetworkCredential("UserName","Password","Domain");
credentials.Add(uriPrefix,"Digest",creds);
calc.Credentials = credentials;
calc.PreAuthenticate = true; //Optional
calc.Add(2,3);
Windows Authentication Integrated
Password not sent in clear text
Proprietary Windows Protocol
Client must be a Windows station
Client sends default current user creds
using System.Net;
SecureCalculator calc = new SecureCalculator();
calc.Credentials = CredentialCache.DefaultCredentials;
calc.PreAuthenticate = true; //Optional
int res = calc.Add(2,3);
Debug.Assert(res == 5);
Log-in Method
Method accepting user name and
password
Useful in conjunction with licensing, billing,
3rd party authentication services
Can also have log-out method
Somewhat less secure than continuous
authentication
Server side:
Store flag in session state
Manually verify in every other method
Log-in Method
Client side:
Enable cookies
Use log-in method before calling sensitive
methods
Can encapsulate in wrapper class
constructor
public class SecureCalculator : WebService
{
bool IsAuthenticated
{
get{
object state = Session["IsAuthenticated"];
if(state != null)
{
return (bool)state;
}
//Must be first request in session
IsAuthenticated = false;
return false;
}
set
{
Session["IsAuthenticated"] = value;
}
}
[WebMethod(EnableSession=true)]
public bool LogIn(string userName,string password)
{
UserManager userManager = new UserManager();
bool authenticated = userManager.Authenticate(userName,password);
IsAuthenticated = authenticated;
return authenticated;
}
[WebMethod(EnableSession=true)]
public void LogOut()
{
IsAuthenticated = false;
}
[WebMethod(EnableSession=true)]
public int Add(int num1,int num2)
{
if(IsAuthenticated == false)
{
throw new UnauthorizedAccessException("Invalid user name or
password passed to this web service");
}
return num1+num2;
}
}
//Client-side
SecureCalculator calc = new SecureCalculator();
calc.LogIn("UserName","Password");
calc.Add(2,3);
calc.LogOut();
calc.Add(2,3); //Throws exception
Log-in Method
Can factor logon functionality to a base
class
Constructor installs custom principal
Web methods declaratively demand
authentication
public class LogInCalculator : LogInWebService
{
[PrincipalPermission(SecurityAction.Demand,Authenticated = true)]
[WebMethod(EnableSession=true)]//Required!
public int Add(int num1,int num2)
{
return num1+num2;
}
}
Soap Headers Authentication
Can add custom information to payload
Not just security
Header-state managed automatically
Server side:
Derive a class from SoapHeader
Add credentials as public member
Add header as public member to web service
definition
Use SoapHeader attribute on sensitive
methods identifying member by name
Manually authenticate
using System.Web.Services.Protocols;
public class AuthenticationHeader : SoapHeader
{
public string UserName;
public string Password;
}
public class SecureCalculator
{
public AuthenticationHeader AuthHeader;
bool Authenticate()//Helper method
{
UserManager userManager = new UserManager();
return userManager.Authenticate(AuthHeader.UserName,
AuthHeader.Password);
}
[SoapHeader("AuthHeader")]
[WebMethod]
public int Add(int num1,int num2)
{
if(Authenticate()== false)
{
throw new UnauthorizedAccessException("Invalid user name or
password passed to this web service");
}
return num1+num2;
}
}
Soap Headers Authentication
Client side:
WSDL-generated wrapper class has
member corresponding to header
Named after type suffixed by Value
null by default
Instantiate header object
Provide credentials
Assign to wrapper class
Can encapsulate by wrapper class if
credentials static
Soap Headers Authentication
public class AuthenticationHeader : SoapHeader
{
public string UserName;//Members only, no properties
public string Password;
}
public class SecureCalculator : SoapHttpClientProtocol
{
public AuthenticationHeader AuthenticationHeaderValue;
//Method wrappers…
}
SecureCalculator calc = new SecureCalculator();
calc.AuthenticationHeaderValue = new AuthenticationHeader();
calc.AuthenticationHeaderValue.UserName = "UserName";
calc.AuthenticationHeaderValue.Password = "Password";
int res = calc.Add(2,3);
Debug.Assert(res == 5);
Soap Headers Authentication
Can issue cookie to optimize credentials
lookup
Payload still contains header info
SOAP Extension
Affects all web methods in web service
Intercepts message before service
invocation
Effectively, .NET to .NET
Can provide generic guest credentials for
unauthenticated users
Can provide processing common to
multiple services
Authentication in Global class
SOAP Extension
Can provide custom message
encryption/decryption
Before message converted into objects
Keys distribution is problematic
Not ideal for true public services
SSL is easier
Encrypts all communication, even non-sensitive
Requires client-side configuration
Programmatic
Administrative
Will be obsolete by GXA / WS-I
WS Security Authentication
Summary
P assw ord in
C lear T ext
R equires
W indow s
O n C onnection
O nly
B asic
Y es
No
Y es
D igest
No
No
Y es
Integrated
No
C lient/S erver
Y es
L og-on m ethod
Y es
No
Y es
Y es
No
S O A P header
w ith cookie
Y es
No
Y es
S O A P E xtension
Y es
C lient/S erver
D epends
S O A P E xtension
w ith encryption
No
C lient/S erver
D epends
S olution
S O A P header
No
WS Impersonation
When using Windows security, .NET
automatically impersonates client
Regardless of authentication mode
When using custom authentication, WS runs
under designated anonymous identity
Even if client provides Windows credentials
With custom identities, service typically
impersonates a designated identity
WS Impersonation
Can manually impersonate client
Log on a Windows account
Impersonation requires authentication
Server-side impersonation
Obtain credentials from login method or
SOAP header
Log-on client using interop
LogonUser()
Security and Impersonation
Server-side impersonation (cont’)
If logon successful
Duplicate security token
Create new Windows Identity
Save impersonation context
Save old security principal
Replace the security principal on both the HTTP
context and current thread
Revert to old identity on call return
.NET Remoting and Security
©2003 IDesign Inc. All rights reserved
Remoting and Security
In .NET 1.1, remoting does not provide
secure channels
No authentication
No call context propagation
Identity
Credentials
Impersonation
Remoting and Security
Can install a custom secure remoting channel
NTLM /Kerberos
Call context propagation
http://msdn.microsoft.com/library/default.asp?url=/library/enus/dndotnet/html/remsspi.asp
www.idesign.net
Likely to be incorporated in .NET 2.0
Enterprise Services Security
©2003 IDesign Inc. All rights reserved
ES Security
Only way in .NET 1.1 for authentication of
remote calls out of the box
Granular control
Encryption
Rich role-based security
Independent of Windows groups
Full security call context propagation
ES Application Security
ApplicationAccessControl attribute
Turning authorization on/off
Security level
Authentication level
Impersonation level
Application Security
Server app
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(
true,//Authorization
AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent,
Authentication=AuthenticationOption.Packet,
ImpersonationLevel=ImpersonationLevelOption.Identify)]
Application Security
Library app:
[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: ApplicationAccessControl(
true,// Authorization
AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent,
//use AuthenticationOption.None to turn off authentication,
//and any other value to turn it on
Authentication=AuthenticationOption.None)]
Component Access Checks
Turn component level access checks on or
off using ComponentAccessControl
attribute
[ComponentAccessControl(true)]
public class MyComponent :ServicedComponent,IMyInterface
{}
Default constructor turns security on
[ComponentAccessControl]
Adding Roles to Application
Use SecurityRole attribute
[assembly: SecurityRole("Manager",
Description = "Can access all components")]
[assembly: SecurityRole("Teller",
Description = "Can access IAccountsManager only")]
Description property is optional
Adding Roles to Application
Overloaded constructors
[assembly: SecurityRole("Manager")]
[assembly: SecurityRole("Manager", false)]
[assembly: SecurityRole("Manager",SetEveryoneAccess = false)]
Use the Marshaler role to create
components
[assembly: SecurityRole("Marshaler",SetEveryoneAccess = true)]
SecureMethod attribute to prevent
marshaler from abusing reflection
At class or method level
Assigning Roles to Component,
Interface, Method
SecurityRole
attribute
[assembly: SecurityRole("Role1")]
[assembly: SecurityRole("Role2")]
[assembly: SecurityRole("Role3")]
[SecurityRole("Role2")]
interface IMyInterface
{
[SecurityRole("Role3")]
void MyMethod();
}
[SecurityRole("Role1")]
public class MyComponent :ServicedComponent,IMyInterface
{}
Verifying Caller’s Role
Membership
Done via SecurityCallContext object
Current call is a static property of same type
using System.Security;//for the security exception
public class Bank : ServicedComponent
{
void TransferMoney(int sum,long accountSrc,long accountDest)
{
bool callerInRole = false;
callerInRole = SecurityCallContext.CurrentCall.IsCallerInRole("Customer");
if(callerInRole)//The caller is a customer
{
if(sum > 5000)
throw(new UnauthorizedAccessException(@"Caller does not have sufficient
credentials to transfer this sum"));
}
DoTransfer(Sum,accountSrc,accountDest);//Helper method
}
//Other methods
}
Design Guidelines and Best
Practices
©2003 IDesign Inc. All rights reserved
Code-Access Security
Crank it all the way up until someone
complains
Design and deploy separate policies for
clients and server
Prefer content to origin based evidence
Identities
The further from the user, the less relevant
its identity
Middle tier components should run under
designated identity
Separate from the user
Separate processes
Class library/Server process based on
running under client identity
Authentication
At every crossing of tier boundary
Privacy is good
Class library/Server based on required
authentication
Library can be very useful
Resources should implicitly trust middle tier
Only authenticate its identity
Authorization
At every crossing of boundary
Can resort to custom RBS
Should impersonate only for authorization,
then revert
More at TechEd
C# Best Practices
DEV312
Distributed Security Practices
DEV354
Building High-Performance Applications with
Visual Studio .NET
DEV326
Application and Library Versioning
DEV343
Software Legends – VS.NET and C# tips and tricks
SWL004
Resources
Programming .NET components
By Juval Lowy, O'Reilly April 2003
www.idesign.net
.NET Master Class
3-4 annually
Upcoming events on
www.idesign.net
Community Resources
Community Resources
http://www.microsoft.com/communities/default.mspx
Most Valuable Professional (MVP)
http://www.mvp.support.microsoft.com/
Newsgroups
Converse online with Microsoft Newsgroups, including Worldwide
http://www.microsoft.com/communities/newsgroups/default.mspx
User Groups
Meet and learn with your peers
http://www.microsoft.com/communities/usergroups/default.mspx
evaluations
SOFTWARE LEGEND
Juval Lowy
Meet the Author’s Book signing
THURSDAY 3rd JULY at 16.15-16.45 hrs
© 2003 Microsoft Corporation. All rights reserved.
This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.
1/--страниц
Пожаловаться на содержимое документа