ict.ken.be

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

Introduction to OAuth2, OpenID Connect and JSON Web Tokens (JWT) 

Categories: Security

By Dominick Baier

Enterprise security 

  • Kerberos/LDAP (intranet)
  • SOAP WS*, XML SAML (internet)

OAuth2 (Authorization Server)

  • Request token for backend consumption
  • Forward token to backend (webapi)

OpenID Connect (Authentication Server)

  • Request token for client consumption
  • Parse and validate token

Security Tokens

  • Security tokens are (protected) data structures
  • Contains information about issuer and subject (claims)
  • signed (tamper proof & authenticity)
  • typically contain an expiration time
  • A client requests a token
  • An issuer issues a token
  • A resource consumes a token (has a trust relationship with the issuer)

SAML 1.1/2.0

  • XML based
  • many encryption & signature options
  • very expressive

Simple Web Token (SWT)

  • Form/URL encoded
  • symmetric signatures only

JSON Web Token (JWT)

  • JSON encoded
  • symmetric and asymmetric signatures (HMAC-SHA256-384, ECDSA, RSA)
  • symmetric and asymmetric encryption (RSA, AES/CGM)
  • http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html

Header: metadata, algorithms & keys used
Claims: Issuer (iss), Audience (aud), IssuedAt (iat), Expiration (exp), Subject (sub), ... application defined claims, Signature

Header.Claims.Signature
{ "typ":"JWT", "alg":"HS256" }
{ "iss":"https://myIssuer", "exp":"1340819380", "aud":"https://myResource", "sub":"alice", "client":"xyz", "scope":["read", "search"]}

http://nuget.org/packages/Microsoft.IdentityModel.Tokens.JWT
SEND: var tokenString = new JWTSecurityTokenHandler().WriteToken(new JWTSecurityToken(...))
RECEIVE: principal = new JWTSecurityTokenHandler().ValidateToken(token, validationParams);

The OAuth 2.0 Authorization Framework (October 2012 - RFC6749, RFC6750)

  • Resource Server, Client, Resource Owner = User, Authorization Server
  • Valet Parking Key Analogy
  • Main goal is to assume the client is not trusted

Authorization Code Flow

  • Resource Owner -> Web Application -> Resource Server
  • 0. Client registers at authorization server 
  • 1a. Owner to AS: GET /authorize?client_id=webapp&scope=resource
  • &redirect_uri=https://webapp/cb&response_type=code&state=123
  • http://zachholman.com/2011/01/oauth_will_murder_your_children/
  • 1b. Owner to client: GET /cb?code=xyz&state=123
  • 2a. WebApp to AS: POST /token Authorization: Basic (client_id:secret) 
  • grant_type=authorization_code&authorization_code=xyz &redirect_uri=https://webapp/cb
  • 2b. AS to WebApp: token response access_token and refresh_token
  • 3. WebApp to Resource Server: GET /Resource
  • 4. send refresh tokens

Implicit Flow

  • 1a. Owner to AS: GET /authorize?client_id=webapp&scope=resource &redirect_uri=https://webapp/cb&response_type=token&state=123
  • 1b. AS to Client: GET /cb#access_token=abc&expires_in=3600&state=123
  • 3. GET /resource

Windows RT - WebAuthenticationBroker.AuthenticateAsync

Resource Owner Credential Flow

  • For trusted applications and devices
  • 1a. Client to AS: POST /token grant_type=password &scope=resource&user_name=owner&password=password
  • 1b. Token response, you should store the token and refresh token, not the credentials
  • Resource owner credentials are exposed to client
  • User should not become accustomed to typing in credentials everywhere

Client Credential Flow

  • No human involved at all
  • POST /token grant_type=client_credentials&scope=resource

OAuth2 abused for authentication by getting userinfo

Client to AS: GET /authorize?client_id=nativeapp&redirect_uri=http://localhost/cb&scope=signin&response_type=token&state=123
AS to Client: GET /CB?access_token
Client to Resource server: GET /userinfo

The Problem
1. User logs into maliciousapp that steals token
2. Malicious developer uses stolen access token in legitimate app (impersonated)

So we now have to write custom code for each provider (https://OAuth.io)

OpenID Connect (on top of OAuth2)

ID Token, UserInfo endpoint, discovery & dynamic registration, session management
Identity Provider, Authorization Endpoint, Token Endpoint, UserInfo Endpoint

  • 1a. user agent to ae: GET /autorize ... scope=openid profile

profile claims: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at
email claims: email, email_verified
address: address
phone: phone_number, phone_number_verified
offline_access: requests refresh token

  • 1b. user agent to IP
  • 2b. token endpoint will return id_token on top of access_token

Client must validate the ID token (especially the audience must be himself)

  • 3a. UserInfo Request

Goal is to allow a client use an arbitrary OpenId Connect provider without code modifications

Eran Hammer (OAuth2 issues)

Protocol vs Framework (over 69 choices), so you can not implement the specification cause you need to build your own protocol.

  • RCF 6749 The OAuth2 Authorization Framework 
  • RFC 6750 OAuth2 Bearer Token Usage
  • RFc 6819 Threat Model and Security Considerations

Bearer Token
A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession). -> so everything depends on the safety of the transport layer, where plenty of developers ignore ssl certificate errors. (ServicePointManager)

Security Theater (Bruce Schneier)

  • Does the webview redirecting make sense?
  • Wouldn't it be better to let the application handle it all?

OAuth2 attack surface everywhere

Facebook Hacks

Specifications needs some refinement (basic profile, MAC tokens, ...)
Current implementations are lacking even by the big guys, let alone the myriad of DIY implementations

Very good & balanced view

Resources

Identity and Access Control in ASP.NET 4.5 

Categories: Security

By Dominick Baier

  • Authentication: Windows, Forms, Federated
  • Authorization: Roles, Claims

ASP.Net security pipeline

  • Request -> BeginRequest -> AuthenticateRequest
  • Look for credential
  • Set Principal (Thread.CurrentPrincipal = authUser; HttpContext.Current.User = authUser;) -> PostAuthenticateRequest
  • Add claims to principal -> AuthorizeRequest 
  • Determine if user is allowed to access resource -> ExecuteHandler 
  • Resource Rendering -> EndRequest
  • Post-processing (error codes, redirect) -> Response

Recommended way to get user is ClaimsPrincipal.Current (instead of Thread.CurrentPrincipal, HttpContext.Current.User, User)

Windows Authentication (Kerberos)

  • Server 2012 allows for additional claims configuration
  • Combination of IIS and ASP.Net settings
<system.webserver>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webserver>

<authentication mode="Windows" />

Claims: Name, PrimarySid, GroupSid, DenyOnlySid

whoami /groups /fo list
whoami /claims (windows server 2012) ad://ext/...

Forms Authentication

  • Produces only a Name Claim, but you can add additional claims using the Role Manager.
<system.webserver>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
</authentication>
</security>
</system.webserver>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
</system.web>
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var success = ValidateUser(model.UserName, model.Password);
if (success)
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToLocal(returnUrl);
}
}

ModelState.AddModelError("", "Username or password wrong.");
return View(model);
}

Membership & Role Manager

  • Lots of methods on the interface you probably don't need.
  • <roleManager cacheRolesInCookie="true" />
  • Limited support for claims

Claims Transformation & Session Management

  • to validate incoming identity data
  • allows adding application specific claims to the principal
public class ClaimsTransformer : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal.Identity.IsAuthenticated)
{
return TransformClaims(incomingPrincipal);
}
return incomingPrincipal;
}
}
  • ClaimsAuthenticationManager needs to be called after the authentication stage eg. PostAuthenticateRequest or using a HTTP module (WS-Federation plumbing) 

Session security token

  • var sessionToken = new SessionSecurityToken(principal, TimeSpan.FromHours(8));
<module runAllManagedModulesForAllRequests="true">
<add name="SessionAuthenticationModule" type="...System.IdentityModel.Services.SessionAuthenticationModule" :>
</modules>
  • FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
  • FederatedAuthentication.SessionAuthenticationModule.SignOut();

Events Pipeline

  • SecurityTokenReceived
  • SessionSecurityTokenCreated
  • SignedIn/SignedOut
  • SignOutError

Sliding Expiration

  • use e.SessionToken to inspect session details in Received handler
if (extendSession)
{
var sam = sender as SessionAuthenticationModule;
e.SessionToken = sam.CreateSessionSecurityToken(...);
e.ReissueCookie = true;
}

Cookie Handling

  • Chunked at 2KB
  • DPAPI and machine key based protection
  • web farms need shared key material
<securityTokenHandlers> 
<remove type="... SessionSecurityTokenHandler ..." />
<add type="... MachineKeySessionSecurityTokenHandker ..." />
</securityTokenHandlers>

Server Side Caching

  • only session token identifier gets serialized into a cookie
  • needs server side (distributed) caching infrastructure
var sessionToken = new SessionSecurityToken(principal, TimeSpan.FromHours(8))
{
IsPersistent = false,
IsReferenceMode = true // cache on server
}
  • Provide your own implementation of SessionSecurityTokenCache for appFabric or memCached.

 

ClaimsAuthenticationManager

  • reject request based on missing identity information
Only authenticated users
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>

Users in role Marketing only
<location path="customers">
<system.web>
<authorization>
<allow roles="Marketing" />
<deny users="*" />
</authorization>
</system.web>
</location>

ClaimsAuthorizationManager
<modules runAllManagedModulesForAllRequests="true">
<add name="ClaimsAuthorizationModule" type=" ... " />
</modules>

<system.identityModel>
<identityConfiguration>
<claimsAuthorizationManager type=" ... " />
</identityConfiguration>
</system.identityModel>

Intra-app Authorization (preferred)

[PrincipalPermission(SecurityAction.Demand, Roles="Marketing"]
public ActionResult AddCustomer() { ... }

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Customer", Operation = "Add")]
public ActionResult AddCustomer() { ... }

[Authorize(Roles = "Sales")] // mvc not in unit tests, no exception, limited to roles
public ActionResult AddCustomer() { ... }

[ClaimsAuthorize("Add", "Customer")] // Thinktecture.IdentityModel, also exists for webapi
public ActionResult AddCustomer() { ... }

var allowed = ClaimsAuthorization.CheckAccess("Get","Customer", id.ToString());
if (allowed) { ... }

[AllowAnonymous]

RegisterGlobalFilters

  • filters.Add(new HandleErrorAttribute());
  • filters.Add(new ClaimsAuthorizeAttribute());

-> don't mix authorization & business logic

External Authentication using WS-Federation

<authentication mode="None" />
<modules>
<add name="WSFederationAuthenticationModule" ... />
<add name="SessionAuthenticationModule" ... />
</modules>
  • Testing with Idenity & Access visual studio extension (no jwt)
  • WS-Federation allows to separate application from authentication which removes complexity from application
  • Security token service responsible for authenticating user, authorization and emitting token + claims
<wsFederation passiveRedirectEnable="true" issuer="https://idsrv/issue/wsfed" realm="http://myapp" />

<issuerNameRegistry type="... ConfigurationBasedIssuerNameRegistry ...">
<trustedIssuers>
<add thumbprint="..." name="STS" />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="ChainTrust" revocationMode="Online" />

<audienceUris>
<add value="http://myapp" />
</audienceUris>
  • Most configuration can be derived from federation metadata (https://idsrv/FederationMetadata/2007-06/FederationMetadata.xml)

Dynamic Configuration

  • Application_Start: FederationAuthentication.FederationConfigurationCreated += FederationAuthentication_FederationConfigurationCreated;

WS-Federation Events

  • SecurityTokenReceived
  • SecurityTokenValidated
  • SessionSecurityTokenCreated
  • SignedIn/SignedOut
  • SignInError/SignOutError
  • RedirectingToIdentityProvider 
var signIn = new SignInRequestMessage(
new Uri("https://idsrv/issue/wsfed"), "http://fooRealm");
var url = signIn.WriteQueryString();
  • FederatedAuthentication.WSFederationAuthenticationModule.SignOut(); -> does not sign-out the user at the token service
  • Server-side Session Caching & Sliding Expiration
  • SessionSecurityTokenCreated: e.SessionToken.IsReferenceMode = true;

Advanced Federation Patterns

Single Sign-On

  • identity provider establishes a logon session with user
  • identity provider is shared across multiple applications

Single Sign-Out

  • /wsfed?wa=wsignout1.0
  • page back to browser that clears out all rps
  • <img src="https://rp1/?wa=wsignoutcleanup1.0" />
public ActionResult SignOut()
{
var fam = FederatedAuthentication.WSFederationAuthenticationModule;

//clear local cookie
fam.SignOut(isIPRequest: false);

//initiate a federated sign out request to the sts.
var signOutRequest = new SignOutRequestMessage(
new Uri(fam.Issuer), fam.Realm
);

return new RedirectResult(signOutRequest.WriteQueryString());
}

Federating with multiple Identity Providers

  • Relying party only "knows" about the R-STS (Resource-STS)

Logical Model

  1. user connects to his identity provider
  2. sends token to resource sts (which trusts identity provider)
  3. user gets transformed token back
  4. user uses token with relying party (which trusts the R-sts)

Physical Model (Home Realm Discovery HRD)

  • user logs into relying party, so browser has to show a selection UI and afterwards remember the decision
  • the whr parameter in WS-Federation allows to pre-select the identity provider
  • https://idsrv/issue/hrd/?wa=wsignin1.0&wtrealm=https://www.myapp.com&whr=[identifier_of_external_idp]
  • <wsFederation homeReal="web" />

ASP.Net Don't do that, do this! 

Categories: .Net

By Damian Edwards

  • Avoid control adapters use css media queries instead
  • Avoid style properties on controls use css stylesheets
  • Avoid page & control callbacks use updatepanel, ajax, webapi, ...
  • Avoid capability detection use client-side feature detection such as Modernizr
  • Avoid request validation use :
    Validate well-formedness of data on the way in (is this submitted value using the correct scheme)
    Encode data on the way out (@foo, <%:foo%>, JavaScriptStringEncode, UrlEncode, ...)
    Do not us <%=, <%# and us @foo.HtmlString() when needed
  • Avoid cookieless forms auth & session use require cookies and secure ssl cookies
  • Make sure EnableViewStateMac = true (must be always on even when not using viewstate)
  • Do not use Medium Trust or any other trust level as a security boundry, place untrusted applications into their own application pools, run each application pool under its own unique identity. http://support.microsoft.com/kb/2698981
  • Do not use <appSettings> to disable our security (only on webfarm roll out) http://msdn.microsoft.com/en-us/library/hh975440.aspx
  • Do not use UrlPathEncode use UrlEncode and sanitize urls with System.Uri
  • Use native IIS modules if you need to hook into PreSendRequestHeaders & PreSendRequestContent, do not use them from within managed IHttpModule instances
  • Do not use async void for page lifecycle events, use Page.RegisterAsyncTask() and set <httpRuntime targetFramework="4.5" /> if using Task
  • Avoid timers, ThreadPool.QUWI as we might tear the AppDomain out from under you.
    Moving to a Windows Service or Worker Role for maximum reliability.
    Using WebBackgrounder if the work needs to be done in-proc: http://nuget.org/packages/WebBackgrounder
  • Avoid reading Request.Form/InputStream before the HandlerExecute event, instead deffer to HandlerExecute.
    Use Request.GetBufferlessInputStream(), Request.Form and InputStream unavailable
    Use GetBufferedInputStream() to get a copy, Request.Form and InputStream available
  • Response.Redirect(string) calls Response.End(), which aborts the current thread in synchronous requests and halts code execution. For asynchronous handlers, Response.End() does not abort the current thread, so code execution continues. If you need to redirect the response, use the method appropriate for the framework you're using. For example, in MVC return a RedirectResult instead of calling Response.Redirect.
  • Do not use EnableViewState but set ViewStateMode="Disabled" at the page directive level and set ViewStateMode="Enabled" only on controls that require state
  • Do not use SqlMembershipProvider, use UniversalProviders which work with all databases that Entity Framework supports including SQL, Azure SQL, SQL Compact, MySQL and more...
  • Avoid long-running requests because asp.net will forcibly release the session object lock at a potentially inopportune time. If needed use WebSockets as it has much lower per-request memory overhead.

AOP in .Net 

Categories: .Net

There are plenty of aop frameworks for .Net but it seems that most of them are not that stable. If you really want to go AOP all the way, are willing to pay the money and can except that you get outgoing pings  on compilations, then you should go for PostSharp (post-compilation). 

I think dynamic proxy of Castle (runtime) is a very nice alternative and not that much slower actually.

https://github.com/KenVanGilbergen/ken.Spikes.Aspects

edit: Just added some testing with SheepAspect, works very nice.

Back to Eli 

Categories: Network Windows

'Back to Eli' is a typical expression used by it-professionals, when they run into people who are supposed to be professionals but actually are missing some basic computer knowledge. Eli the computer guy is a YouTube teacher that makes little movies about technology and he repeats himself so many times that it is impossible you will ever forget...

http://www.youtube.com/user/elithecomputerguy

Why would you hack your dns?

  • block pages from employees on corporate network
  • routers do not allow to loop outside your network and back in

Order in which DNS resolves domain names into ip addresses

  • browser
  • local hosts file
    • Windows: dir C:\Windows\System32\drivers\etc\hosts
    • Linux: ls -l /etc/hosts 
  • local or private dns server
    • mostly the one handing out DHCP eg. router
    • service like dyndns.com
  • public dns servers

Free DNS

  • google.com: 8.8.8.8 and 8.8.4.4 (DNS Client Service)
  • opendns.org: 208.67.222.222 and 208.67.220.220 (filtered dns)

VPN - Virtual Private Networking

  • old routers might not allow vpn pass-through
Page 14 of 40 << < 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 20 > >>