dev354 distributed security practices juval löwy
TRANSCRIPT
![Page 1: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/1.jpg)
DEV354
Distributed Security Practices
Juval Löwy
www.idesign.net
![Page 2: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/2.jpg)
About Juval LöwySoftware architect
Consults and trains on .NET migration and design
MS Regional Director for the Silicon Valley
AuthoredProgramming .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
![Page 3: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/3.jpg)
Outline
.NET role-based security
Web services security
.NET remoting and security
Enterprise Services security
Design guidelines and example (time permitting)
![Page 4: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/4.jpg)
©2003 IDesign Inc. All rights reserved
.NET Role-Based Security
![Page 5: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/5.jpg)
Role-Based Security
User, instead of code permission
What a particular security identity is allowed to do
Identity is user or accountAuthorize based on identity
Roles are by default NT user groupsCan define with some work other options
![Page 6: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/6.jpg)
Declare in code required role memberships
Can apply on methods, but not interfaces
Must set the principal policy first per app domainTypically done in Main()
Role-Based Security
static void Main() { AppDomain currentDomain = Thread.GetDomain(); currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);}
[PrincipalPermission(SecurityAction.Demand,Role=@"<domain>\Manager")]public class MyClass{}
![Page 7: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/7.jpg)
Can demand a particular user (with or without role):
Can demand only that user is authenticated:
Role-Based Security
[PrincipalPermission(SecurityAction.Demand, Role =@"<domain>\Manager", Name ="Bill")]public class MyClass{}
[PrincipalPermission(SecurityAction.Demand,Authenticated=true)]public class MyClass{}
![Page 8: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/8.jpg)
Principal
public interface IPrincipal { IIdentity Identity {get;} bool IsInRole(string role);}
Principal implements IPrincipal System.Security.Principal
An object representing identity and role(s) information
Everything you need to know to make authorization decision
![Page 9: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/9.jpg)
Principal
Every thread has a principal
Available implementations GenericPrincipal
WindowsPrincipal
![Page 10: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/10.jpg)
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 }
Programmatic RBS
![Page 11: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/11.jpg)
©2003 IDesign Inc. All rights reserved
Web Services Security
![Page 12: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/12.jpg)
Security
Based on IIS/ASP.NET
No user/UI pages/formsClient must set credentials programmatically
Windows authenticationBasic, Digest, Integrated
Client has Windows account on server
Set authentication to Windows in config file
All calls are authenticated
![Page 13: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/13.jpg)
Security
CustomGranular control
Must enable anonymous access
Set authentication to None in config file
Various optionsLogon method with cookie
SOAP header
SOAP extension
![Page 14: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/14.jpg)
Windows Authentication - Basic
Client provides credentials
Set Credentials property of wrapper classICredentials
null by default
Available implementationsNetworkCredentials,CredentialCache
Provide domain, user name and password
Can enable pre-authentication
![Page 15: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/15.jpg)
Client sets credentials dynamically
Client may not be a Windows station
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);
Windows Authentication - Basic
![Page 16: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/16.jpg)
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 - Basic
Can encapsulate in constructor ofproxy class if credentials are static
![Page 17: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/17.jpg)
Windows Authentication - Digest
Send hash of passwordIIS verifies password
Requires Active Directory
Client may not be a Windows stationSecureCalculator 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; //Optionalcalc.Add(2,3);
![Page 18: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/18.jpg)
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);
Windows Authentication - Integrated
Password not sent in clear textProprietary Windows Protocol
Client must be a Windows station
Client sends default current user creds
![Page 19: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/19.jpg)
Log-in Method
Method accepting user name and passwordUseful 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
![Page 20: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/20.jpg)
Log-in Method
Client side:Enable cookies
Use log-in method before calling sensitive methods
Can encapsulate in wrapper class constructor
![Page 21: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/21.jpg)
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; }
![Page 22: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/22.jpg)
[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-sideSecureCalculator calc = new SecureCalculator();calc.LogIn("UserName","Password");calc.Add(2,3);
calc.LogOut();calc.Add(2,3); //Throws exception
![Page 23: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/23.jpg)
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; }}
![Page 24: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/24.jpg)
Soap Headers AuthenticationCan 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
![Page 25: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/25.jpg)
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; }}
![Page 26: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/26.jpg)
Soap Headers Authentication
Client side: WSDL-generated wrapper class has member corresponding to header
Named after type suffixed by Valuenull by default
Instantiate header object
Provide credentials
Assign to wrapper class
Can encapsulate by wrapper class if credentials static
![Page 27: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/27.jpg)
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 AuthenticationSoap Headers Authentication
![Page 28: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/28.jpg)
Soap Headers Authentication
Can issue cookie to optimize credentials lookup
Payload still contains header info
![Page 29: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/29.jpg)
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
![Page 30: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/30.jpg)
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 configurationProgrammatic
Administrative
Will be obsolete by GXA / WS-I
![Page 31: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/31.jpg)
WS Security Authentication Summary
![Page 32: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/32.jpg)
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
![Page 33: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/33.jpg)
WS Impersonation
Can manually impersonate clientLog on a Windows account
Impersonation requires authentication
Server-side impersonationObtain credentials from login method or SOAP header
Log-on client using interop
LogonUser()
![Page 34: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/34.jpg)
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
![Page 35: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/35.jpg)
©2003 IDesign Inc. All rights reserved
.NET Remoting and Security
![Page 36: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/36.jpg)
Remoting and Security
In .NET 1.1, remoting does not provide secure channels
No authentication
No call context propagationIdentity
Credentials
Impersonation
![Page 37: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/37.jpg)
Remoting and Security
Can install a custom secure remoting channelNTLM /Kerberos
Call context propagationhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remsspi.asp
www.idesign.net
Likely to be incorporated in .NET 2.0
![Page 38: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/38.jpg)
©2003 IDesign Inc. All rights reserved
Enterprise Services Security
![Page 39: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/39.jpg)
ES Security
Only way in .NET 1.1 for authentication of remote calls out of the boxGranular control
Encryption
Rich role-based security Independent of Windows groups
Full security call context propagation
![Page 40: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/40.jpg)
ES Application Security
ApplicationAccessControl attribute Turning authorization on/off
Security level
Authentication level
Impersonation level
![Page 41: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/41.jpg)
Server app
[assembly: ApplicationActivation(ActivationOption.Server)][assembly: ApplicationAccessControl( true,//Authorization AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent, Authentication=AuthenticationOption.Packet, ImpersonationLevel=ImpersonationLevelOption.Identify)]
Application Security
![Page 42: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/42.jpg)
[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)]
Application Security
Library app:
![Page 43: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/43.jpg)
[ComponentAccessControl(true)]public class MyComponent :ServicedComponent,IMyInterface{}
Turn component level access checks on or off using ComponentAccessControl attribute
Default constructor turns security on [ComponentAccessControl]
Component Access Checks
![Page 44: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/44.jpg)
[assembly: SecurityRole("Manager", Description = "Can access all components")][assembly: SecurityRole("Teller", Description = "Can access IAccountsManager only")]
Adding Roles to Application
Use SecurityRole attribute
Description property is optional
![Page 45: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/45.jpg)
Overloaded constructors
Use the Marshaler role to create components
SecureMethod attribute to prevent marshaler from abusing reflection
At class or method level
[assembly: SecurityRole("Manager")] [assembly: SecurityRole("Manager", false)] [assembly: SecurityRole("Manager",SetEveryoneAccess = false)]
[assembly: SecurityRole("Marshaler",SetEveryoneAccess = true)]
Adding Roles to Application
![Page 46: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/46.jpg)
[assembly: SecurityRole("Role1")][assembly: SecurityRole("Role2")][assembly: SecurityRole("Role3")] [SecurityRole("Role2")]interface IMyInterface{ [SecurityRole("Role3")] void MyMethod();} [SecurityRole("Role1")]public class MyComponent :ServicedComponent,IMyInterface{}
Assigning Roles to Component, Interface, Method
SecurityRoleattribute
![Page 47: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/47.jpg)
Done via SecurityCallContext objectCurrent 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}
Verifying Caller’s Role Membership
![Page 48: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/48.jpg)
©2003 IDesign Inc. All rights reserved
Design Guidelines and Best Practices
![Page 49: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/49.jpg)
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
![Page 50: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/50.jpg)
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
![Page 51: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/51.jpg)
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
![Page 52: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/52.jpg)
Authorization
At every crossing of boundary
Can resort to custom RBS
Should impersonate only for authorization, then revert
![Page 53: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/53.jpg)
More at TechEd
C# Best Practices DEV312
Distributed Security PracticesDEV354
Building High-Performance Applications with Visual Studio .NET
DEV326
Application and Library VersioningDEV343
Software Legends – VS.NET and C# tips and tricksSWL004
![Page 54: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/54.jpg)
ResourcesResourcesProgramming .NET components
By Juval Lowy, O'Reilly April 2003
www.idesign.net
.NET Master Class3-4 annually
Upcoming events onwww.idesign.net
![Page 55: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/55.jpg)
Community Resources
Community Resourceshttp://www.microsoft.com/communities/default.mspx
Most Valuable Professional (MVP)http://www.mvp.support.microsoft.com/
NewsgroupsConverse online with Microsoft Newsgroups, including Worldwidehttp://www.microsoft.com/communities/newsgroups/default.mspx
User GroupsMeet and learn with your peershttp://www.microsoft.com/communities/usergroups/default.mspx
![Page 56: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/56.jpg)
evaluationsevaluations
![Page 57: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/57.jpg)
SOFTWARE LEGENDSOFTWARE LEGENDJuval LowyJuval Lowy
THURSDAY 3rd JULY at 16.15-16.45 hrs
Meet the Author’sMeet the Author’s Book signingBook signing
![Page 58: DEV354 Distributed Security Practices Juval Löwy](https://reader035.vdocuments.mx/reader035/viewer/2022062519/5697bffc1a28abf838cc143b/html5/thumbnails/58.jpg)
© 2003 Microsoft Corporation. All rights reserved.© 2003 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.