ict.ken.be

Delivering solid user friendly software solutions since the dawn of time.

Introduction to Identity and Access Control 

Categories: .Net Security

by Dominick Baier
dbaier@leastprivilege.com
http://www.leastprivilege.com
@leastprivilege Principals & Identities

interface IIdentity
{
	bool IsAuthenticated { get; }
	string AuthenticationType { get; }
	string Name { get; } 
}

interface IPrincipal
{
	IIdentity Identity { get; }
	bool IsInRole(string roleName);
}
  • Thread.CurrentPrincipal Every thread can have his own client security context Plumbing sets it, application gets it.
WindowsPrincipal
var id = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(id);

principal.IsInRole("Builtin\\Users") //Don't use because they are localized.
var localAdmins = new SecurityIdentifier(WellknownSidType.BuiltinAdministratorSid, null);
var domainAdmins = new SecurityIdentifier(WellknownSidType.AccountDomainAdminsSid, id.User.AccountDomainSid);
var users = new SecurityIdentifier(WellknownSidType.BuiltinUsersSid, null);

var account = new NTAccount(id.name);
var sid = account.Translate(typeof(SecurityIdentifier));

var groups = user.Groups.Translate(typeof(NTAccount));
GenericPrincipal

var roles = new string[] { "Sales", "Marketing" };
var p = new GenericPrincipal(new GenericIdentity("bob"), roles);
Thread.CurrentPrincipal = p;
p.Identity.Name
Role-based access control (RBAC)

if p.IsInRole("Sales") {} //returns true/false
new PrincipalPermission(null, "Development").Demand(); //will throw security exception if fails

[PrincipalPermission(SecurityAction.Demand, Role="Development"] //hard to unit test
private static void DoDevelopment() {}
  • Claims are statements
  • How do we handle things no longer in corporate network like cloud, partners and customers ?
  • Bell-Lapadula Model for goverment and military document security.

2002 Identity
2006 WCF System.IdentityModel with SecurityToken
2009 WIF Microsoft.IdentityModel with IClaimsIdentity & IClaimsPrincipal
2012 .NET 4.5 System.IdentityModel & System.Security.Claims eg. Bob is an administrator, Jim's email address is jim@foo.com, ...

public class Claim
{
	public virtual string Type { get; }
	public virtual string Value { get; }
	public virtual string Issuer { get; }
	//...
}

class ClaimsIdentity : IIdentity
{
	IEnumerable<Claim> Claims { get; }
}

class ClaimsPrincipal : IPrincipal
{
	ReadOnlyCollection<ClaimsIdentity> Identities { get; }	
}

var claim = new Claim("name", "dominick");
var claim = new Claim(ClaimTypes.Name, "dominick");

var Claims = new List<Claim>
{
	new Claim(ClaimTypes.Name, "dominick"),
	new Claim(ClaimTypes.Email, "dominick@foo.com"),
	new Claim(ClaimTypes.Role, "Geek"),
	new Claim("http://myClaims/location", "Heidelberg")
};

var id = new ClaimsIdentity(claims);
id.IsAuthenticated -> false because you can add claims to anonymous
var id = new ClaimsIdentity(claims, "Console App", ClaimTypes.Name, ClaimTypes.Role); //what do name and isrole map too for legacy
id.IsAuthenticated -> true

var cp = new ClaimsPrincipal(id); //prefered entry point
Thread.CurrentPrincipal = cp;
-> var cp = ClaimsPrincipal.Current;

var email = cp.FindFirst(ClaimTypes.Email).Value;

RolePrincipal, GenericPrincipal, WindowsPrincipal : ClaimsPrincipal : IPrincipal
Generalization & Specialization Interface level: IIdentity : Name, AuthenticationType, IsAuthenticated
Claims identity: ClaimsIdentity : Claims, FindAll(), FindFirst(), HasClaim()
Domain specific: WindowsIdentity : Token, Impersonate(), User/Device

  • Claims Always try to use ClaimsIdentity for your custom principal implementation.
class CorpIdentity : ClaimsIdentity
{
	public CorpIdentity(string name, string reportsTo, string office)
	{
		AddClaim(new Claim(ClaimTypes.Name, name));	
		AddClaim(new Claim("reportsto", reportsTo));	
		AddClaim(new Claim("office", office));	
	}
	
	public string office
	{
		get { return FindFirst("reportsto").Value; }	
	}
}
  • Services Unification of various credential formats to common ClaimsPrincipal representation Windows/Kerberos, Forms Authentication, HTTP basic authentication, SSL client certificates, WS-Security tokens, SAML, extensible, ...
  • Processing Pipeline Request (xml/binary/text) -> Security token handler (seserialization/validation) -> Claims transformation (skipped when session available) -> Security Session Management -> Session Security Token -> Authorization
public class ClaimsTransformer : ClaimsAuthenticationManager
{
	public overrride ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
	{
		var name = incomingPrincipal.Identity.Name;
		if (string.IsNUllOrWhiteSpace(name)) throw new SecurityException("Name claim is missing");
		if (incomingPrincipal.Identity.IsAuthenticated)
		{
			return TransformClaims(incomingPrincipal);
		}
		return incomingPrincipal;
	}
}
<system.identityModel>
<identityConfiguration>
	<claimsAuthenticationManger type="assembly/class" />
</identityConfiguration>
</system.identityModel>
var p = new WindowsPrincipal(WindowsIdentity.GetCurrent());
Thread.CurrentPrincipal = FederationAuthentication.FederationConfiguration.identityConfiguration.ClaimsAuthenticationManager.Authenticate("none", p) as IPrincipal;
  •  Session management Preserve a ClaimsPrincipal across round trips (cookies, ws-secureconversation) 
var sessionToken = new SessionSecurityToken(principal, TimeSpan.FromHours(8));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
  • Data protection api, zero configuration but only for single server.
  • For webfarms use machinekey or ssl-certificate to protect your cookie.
  • Roundtrip the identity and cache the claims principal.
  • Claims authorization manager Extensibility point for loading/parsing authorization policy
  • Extensibility point for mapping operations/resources to required claims
  • Auto-invoked during request processing
  • Application code should not check for claims directly 
public class AuthorizationContext
{
	public AuthorizationContext();
	public Collection<Claim> Action { get; }
	public ClaimsPrincipal Principal { get; }
	public Collection<Claim> Resource { get; }
}

<claimsAuthorizationManager type="ClaimsAuthorizationManagerClass, theAssembly" >
	<policy file="foo.xml" /> 
</claimsAuthorizationManager>
public class ClaimAuthZManager : ClaimsAuthorizationManager
{
	public override bool CheckAccess(AuthorizationContext context)
	{
		//inspect context and make authorization decision
		var resource = context.Resource.First().Value;
		var action = context.Action.First().Value;
		if (action == "Show" && resource == "Castle")
		{
			var hasCastle = context.Principal.HasClaim("http://myclaims/hasCastle", "true");
			return hasCastle;
		}
		return false;
	}
	override void LoadCustomConfiguration(XmlNodeList nodelist)
	{
		base.LoadCustomConfiguration(nodelist);
	}
}
[ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "Add", Resource = "Customer")]
public void AddCustomer(Customer customer) { ... }
void Print(Document document)
{
	if (ClaimsPrincipalPermission.CheckAccess(document.Printer, "Print")) { ... }
}
var authZ = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.Claims.ClaimsAuthZManager;
authZ.CheckAccess(...);

http://msdn.microsoft.com/en-us/library/system.security.claims.claimsauthorizationmanager.aspx

Protocol support

  • Web Application : WS-Federation
  • SOAP : WS-Trust & WS-Security
  • WebApi : OAuth2 Client -> STS -> Token -> Client -> Token -> Relying Party/Application (no authentication on RP) <saml:Assertion ... Signature ...> tokens for seamless third party authentication

Security Token Services

  • Microsoft Active Directory
  • Federation Service 2
  • IBM Tivoli Federation Manager
  • Oracle Identity Manager
  • Ping Federate
  • Thinktecture .NET 4.5 (http://identityserver.codeplex.com/) ASP.Net
<authentication mode="windows">
	<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

<system.identityModel configSource="identity.config" />
<system.identityModel>
	<identityConfiguration>
		<audienceUris />>
		<claimsAuthenticationManager type="Security.ClaimsTransformer, Web" />
		<issuerNameRegistry />
	</identityConfiguration>
</system.identityModel>

private void EstablishSession(ClaimsPrincipal principal)
{
	if (HttpContext.Current != null)
	{
		var sessionToken = new SessionSecurityToken(principal);
		FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
	}
}
<system.webServer>
	<add name="ClaimsTransformationModule" type="Security.ClaimsTransformationHttpModule" />
	<add name="SessionAuthenticationModule" type="Security.IdentityModel.Services.SessionAuthenticationModule, ..." />
</system.webServer>

<system.identityModel.services configSource="identity.Services.config" />
<system.identityModel.services>
	<federationConfiguration>
		<wsFederation passiveRedirectionEnable="true" issuer="remote login page location"
		realm="" requireHttps="true" />
		<cookieHandler requireSsl="true" />
	</federationConfiguration>
</system.identityModel>

for wcf: <bindings> <ws2007FederationHttpBinding>

webapi

[Authorize]
public class IdentityController : ApiController
{
	public Identity Get()
	{
		return new Identity(User.Identity);
	}
}

Mercurial - Notes 

Categories: Mercurial Notes

Mercurial - HG

http://mercurial.selenic.com

  • Created by Matt Mackall at same time Git started.
  • DVCS written in Python
  • No partial commits (only atomic commits)
  • Three-way merging

Source control for tracking and sharing
Terms: Source, revision, version controlling
Types: Manual merging, File locking, Version merging
Architecture: Centralized, Distributed (no central server, appointed central server or lieutenants/commander)

Install TortoiseHg
Global settings
Username: firstname lastname <email address> (is mostly used as a convention)
Extensions: graphlog
-> updates the mercurial.ini file in each users root (c:/users/user/mercurial.ini)

Commands
hg help
hg init / hg ci (.hg folder is repository for all subfolders)
hg status
hg add
hg add foo.txt
hg commit (will prompt for change message, will commit all folders, emty folders will not be added !)
hg commit -m "your message" / hg ci -m "message"
hg log --limit 5 / hg -l 5 (will show last 5 changes)
hg glog

hg diff
hg revert --all
hg revert foo.txt (will create a copy of your discarded file in same folder with .orig extension)
hg revert foo.txt --no-backup

Ignore files for adding:

  • create .hgignore in root 
syntax: glob
*.orig
[Bb]in
foo.*
foo??.txt

syntax: regexp

You can only undo the most recent commit and when it has not yet been shared with another repository.
hg rollback

hg update 1 (locally: revision number of the changeset)
hg update e99fffee (globally: changeset identifier)

del foo.txt
hg remove foo.txt

Working with a server

md repository
hg init
hg serve (will run http server on localhost:8000)
cd .hg

  • create file hgrc
[web]
push_ssl=false
allow_push=*

hg clone http://localhost:8000 hgclientfolder
hg push
hg out (compare local outgoing with server version)
hg incoming (compare local incoming from server)

Pulling changes from server, will update your local repository but not your working copy!
hg pull
hg update

Branching
Implicit branches
Created by a commit
Keep time of changes short

Clones

  • Can be used if we need to bugfix something quickly and we are in the middle of a development we can not yet check in.
  • Although multiple clones on one machine is not advised.
  • Fork if you want to create a new flavor and do not have the intention to commit back
  • Fork if you want to contribute on open source project, do all your changes and when finished you request a pull request to the main repository.

Named branches

  • we always start in default
  • branch name stored with changeset
  • mostly we create a branch for releases to other environments

hg update -r 6
hg branch
hg branches
hg identify -n
hg branch production (use bookmark feature if you want same branching strategy as git)
hg ci -m "quickfix"
hg update default

hg up branchtobeclosed
hg ci --close-branch -m"no longer needed"
hg up default

Merging 
hg heads
hg up default (make sure you are in branch you want to merge to)
hg merge production
hg ci -m "merge"

hg parent (show the changeset that's in the working directory)
hg paths (shows a list of known remote repositories)
hg tag version-1.0 (marks the hex number of the changeset)
hg tag -r . Version-1.1
.hgtags sometimes needs merging too :)

HTTP Fundamentals - Notes 

Categories: Network Notes

by Scott Allen

  • HTTP: HyperText Transfer Protocol
  • URL: Uniform Resource Locator

urlScheme://host:port/urlPath?q=query#fragment

URL Encoding
Safe Characters: a-z A-Z 0-9 $-_.+*'(),

Common MIME Types

  • Type/Subtype
  • application/atom+xml
  • application/json
  • image/gif
  • image/png
  • video/mp4
  • text/xml
  • text/html
  • text/plain

Content Negotiation

html: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4
date: http://tools.ietf.org/html/rfc822#section-5.1

HTTP Transaction: HTTP Request + HTTP Response

telnet odetocode.com 80
GET /odetocode.jpg HTTP/1.1
Host: www.odetocode.com
enter key twice

HTTP Request Methods
GET, POST, PUT, DELETE, HEAD
Safe versus Unsafe: http://en.wikipedia.org/wiki/Post/Redirect/Get

Request Message
[method] [URL] [version]
[headers]
[body]

GET / HTTP/1.1
Host: server.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:fr-FR
Accept-Encoding: gzip,deflate,sdch
Date: Fri, 9 Aug 2002 21:12:00 GMT
Referer, User-Agent, Accept, Cookie, If-Modified-Since, Accept-Charset

The default q value is 1.0 preference of accept

Response Message
[version] [status] [reason]
[headers]
[body]

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
X-headers are reserved for nonstandard headers

301 permanent do not come here again
302 temporarly eg. redirect after sign-in

TCP: Transmision Control Protocol -> Reliable (Transport)
not UDP: User Datagram Protocol -> Unreliable
Opens a socket on IP
IP: Internet Protocol (Network)
Ethernet (Data Link)

private static string GetResource(Uri uri)
{
var hostEntry = Dns.GetHostEntry(host);
var socket = CreateSocket(uri.hostEntry);
SendRequest(socket, uri.Host, uri.PathAndQuery);
return GetResponse(socket);
}

private static Socket CreateSocket(IPHostEntry hostEntry)
{
const int httpPort = 80;
var endPoint = new IPEndPoint(hostEntry.AddressList[0], httpPort);
var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, Protocol.Tcp);
socket.Connect(endPoint);
if (socket.Connected) return socket;
return null;
}

private static void SendRequest(Socket socket, string host, string resource)
{
var requestMessage = String.Format(
"GET {0} HTTP/1.1\r\n" +
"Host: {1}\r\n" +
"\r\n", resource, host
);
var requestBytes = Encoding.ASCII.GetBytes(requestMessage);
socket.Send(requestBytes);
}
private static string GetResponse(Socket socket)
{
int bytes = 0;
byte[] buffer = new byte[256];
var result = new StringBuilder();
do
{
bytes = socket.Receive(buffer);
result.Append(Encoding.ASCII.GetString(buffer, 0, bytes));
}
return result.ToString();
}

http://wireshark.org
Capture Options
Capture Filter: host odetocode.com
3 step TCP Handshake

www.ietf.org/rfs/rfc2616.txt
A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.

http://en.wikipedia.org/wiki/Slow-start

Default connection close about 5 seconds.
Shared hosts often send 'Connection: close' in header to allow more connections.

HTTP Architecture

http://odata.netflix.com/v2/Catalog/ (https://hidemyass.com/)
REST: www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Forward Proxy: using a proxy as an access control device (by dropping messages)
Reverse Proxy: eg. loadbalancer
Fiddler installs itself as a local 127.0.0.1:8888 proxy in your browser

Caching
Chrome: about:cache

Cache It: HTTP/1.1 200 OK GET
Don't cache: PUT, POST, DELETE

Cache-Control: private, max-age=0
Expires: ... should no longer be used
Pragma: ... should no longer be used

Cache Control

  • public: A response for everyone
  • private: A response for a single user
  • no-cache, must-revalidate: Don't cache the response
  • no-store: You never saw this response
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));

If-Modified-Since: Wed, 14 Sep 2011 19:02:18 GMT

Etag: "07f2a22ffd9cc1:0" hash of the resource
If-None-Match: "07f2a22ffd9cc1:0"

HTTP Security
Cookies and Authentication
http://tools.ietf.org/html/rfc6265
About 4kb max

Saving State
ViewState <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/foo" />
Store in database
SessionState Store
Cookies

Set-Cookie: ASP.NET_SessionId=foo; path=/; HttpOnly

domain=.searchengine.com (include subdomains)
expires=Monday, 09-July-2012 21:12:00 GMT

Security

Basic Authentication
WWW-Authenticate: Basic realm="localhost"
Authorization: Basic base64encodedusernameandpassword

Digest Authentication
WWW-Authenticate: Digest realm="localhost", qop="auth,auth-int", nonce="...", opaque="..."

Windows Authentication
WWW-Authenticate: Negotiate
NTLM and Kerberos

Forms Authentication
Location: /login?ReturnUrl=/account

OpenID: Google, Yahoo, myOpenId, StackExchange, facebook

HTTPS
Adds a SSL/TLS layer inbetween application and transport layer
Certificate with Public/Private key
Everything except the hostname

XUnit Inconclusive 

Categories: Testing

When you can not use 2012 as a test runner, you can download xunit contrib that will plugin to Visual Studio 2012 with Resharper 7.1

In case you were using MSTest before: 

I understand that unit test should be failing or passing in theory, but while coding 'inconclusive' is just handy to remember where you are. So you can use [Fact(Skip = "Reason")]

Add setting to custom mojoPortal module 

Categories: mojoPortal

Small example showing how to add a Custom Css Class to your module.

  1. Add code using the setting eg. Page_Load
  2. Update config xml eg. Setup/applications/FeatureDefinitions/MyModule.config
  3. Add resource in App_GlobalResources eg. CustomCssClassSetting as 'Custom Css Class'
  4. Run the system setup
if (Settings.Contains("CustomCssClassSetting"))
{
    var instanceCssClass = Settings["CustomCssClassSetting"].ToString();
    if (instanceCssClass.Length > 0) { pnlOuterWrap.SetOrAppendCss(instanceCssClass); }
}
<featureSetting
   resourceFile="MyModuleResources"
   grouNameKey=""
   resourceKey="CustomCssClassSetting"
   defaultValue=""
   controlType="TextBox"
   controlSrc=""
   helpKey="custom-module-css-class-help"
   sortOrder="3000"
   regexValidationExpression="^([\s]?[a-zA-Z]+[_\-a-zA-Z0-9]+)*\z+"
/>
Page 24 of 43 << < 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 40 > >>