Stormpath's .NET Developer Evangelist, Nate Barbettini, walks us through token authentication in ASP.NET Core. You will learn how sessions work, how token authentication works, and some of the intricacies of token authentication with ASP.NET Core.
2. Welcome!
• Agenda
• Stormpath 101 (5 mins)
• Get Started with iOS (40 mins)
• Q&A (10 mins)
• Remy Champion
Marketing
• Nate Barbettini
.NET Developer Evangelist
3. Speed to Market & Cost Reduction
• Complete Identity solution out-of-the-box
• Security best practices and updates by default
• Clean & elegant API/SDKs
• Little to code, no maintenance
5. Overview
● How Sessions Work (And Why They Suck)
● How Token Authentication Works
● Tokens + ASP.NET Core
6. How Sessions Work
Browser
ASP.NET
(1) POST /login
(2) 200 OK
Set-Cookie: session=dh7jWkx8fj;
(3) GET /profile
(4) 200 OK
Cookie: session=dh7jWkx8fj;
Log In:
nate@example.com
MySecretPassword123!
Open Profile Page
Profit!
Session
Store
8. How Token Authentication Works
Browser
ASP.NET
(1) POST /login
(2) 200 OK
eyJ0eXAiOiJKV...
Stored token: eyJ0eXAiOiJKV...
(3) GET /profile
(4) 200 OK
Authorization: Bearer eyJ0eXAiOiJKV...
Log In:
nate@example.com
MySecretPassword123!
Open Profile View
Profit!
10. ● A JWT is a JSON object that’s been stringified and base64-encoded:
Anatomy of JSON Web Tokens
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpb
mUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0NjU1ODAwNzEsImV4cCI6MTQ
5NzExNjA3NywiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoib
mF0ZUBleGFtcGxlLmNvbSIsImlzQXdlc29tZSI6InRydWUiLCJwcm9
2aWRlcyI6WyJzdGF0ZWxlc3MiLCJhdXRoZW50aWNhdGlvbiJdfQ.VX
rLbyQeJfDmwTAg-JnRsyD23RYMQJshTx79z2STu0U
Red = Header
Blue = Payload (“claims”)
Green = Cryptographic signature (JWS)
12. ● Cryptographically signed by the server
● Signature guarantees it hasn’t been forged or altered
Token Security
13. ● Token expiration (exp claim) and not-before (nbf claim)
● Optional token revocation using a nonce (jti claim)
● Use HTTPS (TLS) everywhere!
● Store tokens securely
Token Security
14. Where to Store Tokens?
● On mobile: local device storage, sent via HTTP headers
● On the web: cookies, or HTML5 web storage (via HTTP headers)
15. Where to Store Tokens?
● HTML5 web storage: vulnerable to XSS (cross-site scripting)
● Cookies: not vulnerable to XSS
○ Set the HttpOnly and Secure flags
○ Still need to protect against CSRF
● More info: Stormpath blog
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
16. Generating Tokens in ASP.NET Core
● This functionality was included in ASP.NET, but was removed from
ASP.NET Core.
● The community has stepped up to build this functionality:
○ Stormpath ASP.NET Core plugin
○ Thinktecture IdentityServer4
○ AspNet.Security.OpenIdConnect.Server
○ OpenIddict
17. ● Basic JWT creation: JwtSecurityTokenHandler
Generating Tokens in ASP.NET Core
using System.IdentityModel.Tokens.Jwt;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
// Create the JWT and write it to a string
var jwt = new JwtSecurityToken(
issuer: _options.Issuer,
audience: _options.Audience,
claims: claims,
notBefore: now,
expires: now.Add(TimeSpan.FromMinutes(5)),
signingCredentials: _options.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
18. ● Nate’s simple example on Github:
https://github.com/nbarbettini/SimpleTokenProvider
Generating Tokens in ASP.NET Core
19. Validating Tokens in ASP.NET Core
● Validating incoming Bearer (HTTP header) tokens is easy!
var mySecretKey = new SymmetricSecurityKey(
Encoding.ASCII.GetBytes("mysupersecret_secretKey!123"));
app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
AutomaticAuthenticate = true,
TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = mySecretKey,
ValidateLifetime = true,
ValidIssuer = "MyApplication",
ValidAudience = "https://app.example.com",
}
});
20. Validating Tokens in ASP.NET Core
● JWTs in cookies?
See SimpleTokenProvider on Github.
21. ● Hosted user identity and authentication/authorization API
● Token generation and authentication
● Single Sign-On across multiple applications
● Multi-tenant support for SaaS applications
● Free (forever) developer tier
About Stormpath
22. Token authentication in ASP.NET Core tutorial
https://stormpath.com/blog/token-authentication-asp-net-core
Stormpath + ASP.NET Core quickstart
https://docs.stormpath.com/dotnet/aspnetcore/latest/quickstart.html
Web storage vs. cookies
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
Nate’s SimpleTokenProvider sample
https://github.com/nbarbettini/SimpleTokenProvider
Q&A
Intro - who I am: Stormpath .NET dev evangelist.
Stormpath is all about helping developers use best practices for security and providing tools to make it easier to build secure applications.
I’ve had a chance to be on the bleeding edge with ASP.NET Core - lots of stuff has changed!
The browser POSTs the user’s credentials to your server. A session ID is created or updated that identifies the user.
The session ID is pushed down to the browser inside a cookie.
The cookie is included on each subsequent request. The session ID is used to find the session information in the session store (either in-memory or in a database).
If the session lookup succeeds, the request is authenticated.
If the session store is in-memory, each user must stay on the server they started with.
The client POSTs the user’s credentials to your token endpoint. Your server generates a signed token that represents the user’s authentication ticket.
The token is sent back to the client and stored somewhere locally.
When the client needs to make another API request, it sends the token along with the request.
Your API inspects the token to ensure it hasn’t been tampered with. The token includes the information necessary to prove the user is authenticated. The server doesn’t need to do any lookups.
Any server could have fulfilled the request, not just the one that the user authenticated with.
The token itself contains enough information about the user, so the server doesn’t need to look up their session in a session store.
It’s separated into two or three sections by periods.
Header: Metadata
Body: Payload or “claims”
In this case, NOT encrypted.
You might be wondering: can’t anyone just change these values?
Security needs to be airtight if we are going to implicitly trust something the client is sending us.
If I can get a malicious script to run on your page, I can do localStorage.getItem and grab your token.
Microsoft built a middleware component for this.
Great for mobile APIs.