Absicherung von Microservices mit OpenID Connect und Spring Security 5

JAX, Mainz 7.5.2019

Slides: https://andifalk.github.io/jax-2019-openid-connect-spring-security
Demos: https://github.com/andifalk/jax-2019-openid-connect-spring-security

Andreas Falk

Novatec Consulting GmbH

andreas.falk@novatec-gmbh.de / @andifalk (Twitter)

https://www.novatec-gmbh.de

Agenda

Intro to OAuth 2.0 & OpenID Connect 1.0

Current Discussions & Best Practices in OAuth 2.0/OIDC

OAuth 2 & OIDC with Spring Security 5 (Live Demo)

OAuth 2.0

101

RFC 6749: The OAuth 2.0 Authorization Framework
RFC 6750: OAuth 2.0 Bearer Token Usage
RFC 6819: OAuth 2.0 Threat Model and Security Considerations

What is OAuth 2.0?

OAuth 2.0 is an authorization delegation framework

OAuth 2.0 Model

OAuth 2.0 Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Implicit --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Authorization Code Grant Flow

Demo Time

Authorization Code Grant Flow

In Action

Implicit Grant Flow

Authorization Request

GET https://authserver.example.com/authorize

?response_type=token

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

Authorization Response

HTTP/1.1 302 Found

Location: https://client.abc.com/callback

#access_token=2YotnFZFEjr1zCsicMWpAA

&token_type=bearer

&expires_in=3600

&scope=api.read api.write

&state=xyz

OpenID Connect 1.0

(OIDC)

101

OpenID Connect Core 1.0
OpenID Connect Dynamic Client Registration 1.0
OpenID Connect Discovery 1.0

OpenID Connect 1.0 is for Authentication

OAuth 2.0 is not an authentication protocol

OIDC Model

Additions to OAuth 2.0

Id Token (JWT format)

User Info Endpoint

Standard Scopes

Hybrid Grant Flow

OpenID Provider Configuration Information

ID Token

JSON Web token (JWT)

Base 64 Encoded JSON Formatted Value of...

...Header

...Payload

...Signature


                            GET / HTTP/1.1
                            Host: localhost:8080
                            Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N...
                        

JSON Web Token (JWT)

Header


                            {
                              typ: "JWT",
                              alg: "RS256"
                            }
                        

Payload


                            {
                              iss: "https://identity.example.com",
                              aud: "my-client-id",
                              exp: 1495782385,
                              nonce: "N0.46824857243233511495739124749",
                              iat: 1495739185,
                              at_hash: "hC1NDSB8WZ9SnjXTid175A",
                              sub: "mysubject",
                              auth_time: 1495739185,
                              email: "test@gmail.com"
                            }
                        

ID Token Claims

Scope Required Description
iss X Issuer Identifier
sub X Subject Identifier
aud X Audience(s) of this ID Token
exp X Expiration time
iat X Time at which the JWT was issued
auth_time (X) Time of End-User authentication
nonce -- Associate a client with an ID Token

Token Validation

User Info Endpoint


                            GET /userinfo HTTP/1.1
                            Host: identityserver.example.com
                            Authorization: Bearer SlAV32hkKG
                        

                            HTTP/1.1 200 OK
                            Content-Type: application/json

                            {
                             "sub": "248289761001",
                             "name": "Jane Doe",
                             "given_name": "Jane",
                             "family_name": "Doe",
                             "preferred_username": "j.doe",
                             "email": "janedoe@example.com",
                             "picture": "http://example.com/janedoe/me.jpg"
                            }
                        

OpenID Connect 1.0 Configuration

https://example.com/.well-known/openid-configuration


                            {
                              "authorization_endpoint": "https://idp.example.com/auth",
                              "grant_types_supported": [
                                  "authorization_code",
                                  "implicit",
                                  "refresh_token"
                              ],
                              "issuer": "https://idp.example.com",
                              "jwks_uri": "https://idp.example.com/keys",
                              "token_endpoint": "https://idp.example.com/token",
                              "userinfo_endpoint": "https://idp.example.com/userinfo",
                              ...
                            }
                        

OpenID Connect Discovery 1.0

Discussions & Best Practices

In OAuth 2.0 and OpenID Connect

4th OAuth Security Workshop 2019

Stuttgart

https://sec.uni-stuttgart.de/events/osw2019


https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926

OAuth 2.0 Security Best Current Practice

Torsten Lodderstedt and Daniel Fett

OAuth 2.0 Security Best Current Practice

Implicit Flow Attacks


Source: Torsten Lodderstedt and Daniel Fett

OAuth 2.0 for Browser-Based Apps

David Waite (PingFederate)

OAuth 2.0 for Browser-Based Apps

OAuth 2.0 for Browser-Based Apps

Content-Security Policy

Use a unique redirect URI

Do NOT use refresh tokens

OAuth 2.0 for Browser-Based Apps

Other Known OAuth 2.0 Attacks

  • Lack of CSRF protection
  • Authorization code leakage and replay
  • Authorization code injection
  • Open Re-directors
  • State leakage and replay
  • Insufficient Redirect URI matching
  • Too powerful access tokens
  • Mix-Up Attacks

Open Redirect !!

“OAuth 2.1” Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code (PKCE) X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Authorization Code (PKCE) --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Proof Key for Code Exchange by OAuth Public Clients (PKCE)

(“Pixy”)

Mitigates authorization code attacks

Mitigates token leakage in SPAs

Proof Key for Code Exchange by OAuth Public Clients

PKCE - Authorization Request

GET https://authserver.example.com/authorize

?response_type=code

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

&code_challenge=xyz...&code_challenge_method=S256

PKCE - Token Request

Client-Id=123, Client-Secret=456

POST https://authserver.example.com/token

Content-Type:
application/x-www-form-urlencoded

grant_type=authorization_code&code=ab23bhW56Xb

&redirect_uri=https://client.abc.com/callback

&client_id=123&client_secret=456

&code_verifier=4gth4jn78k_8

Steal Tokens via XSS

“XSS is Game-Over for OAuth 2” (Jim Manico)

OAuth 2 Access Token JWT Profile

Vittorio Bertocci (Auth0)

JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens

OAuth 2 Access Token JWT Profile

Required claims: iss, exp, aud, sub, client_id

Consider privacy restrictions for identity claims

Authorization claims according to SCIM Core (RFC7643):

  • Groups
  • Entitlements
  • Roles

System for Cross-domain Identity Management (SCIM)

Token Binding

RFC8471: The Token Binding Protocol Version 1.0

RFC8472: (TLS) Extension for Token Binding Protocol Negotiation

RFC8473: Token Binding over HTTP

OAuth 2.0 Mutual TLS Client Authentication and Certificate-Bound Access Tokens

Google - Intent to Remove: Token Binding

Further Internet-Drafts for OAuth 2

List of OAuth 2 Internet-Drafts (by date)

Demo Time

OAuth 2.0 & OpenID Connect 1.0

With Spring Security 5

“Legacy” Spring Security OAuth 2 Stack

“New” Spring Security
OAuth 2 Stack

Demo application

What's new in
Spring Security
5.2 & 5.3

Spring Security 5.2 (08/2019)

Spring Security 5.2.0 M2 GitHub Issues
Spring Security 5.2.0 M3 GitHub Issues
Spring Security 5.2.0 RC1 GitHub Issues

OAuth 2.0 Token Introspection

Opaque Tokens


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                                @Override
                                protected void configure(HttpSecurity http)
                                        throws Exception {
                                    http.oauth2ResourceServer()
                                            .opaqueToken()
                                                .introspectionUri(this.introspectionUri)
                                                .introspectionClientCredentials(
                                                    this.clientId, this.clientSecret);
                                }
                            }
                        
https://github.com/spring-projects/spring-security/issues/5200

Resource Server Multi-tenancy


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                                @Override protected void configure(HttpSecurity http) {
                                    http.oauth2ResourceServer()
                                        .authenticationManagerResolver(
                                            multitenantAuthenticationManager());
                                }

                                @Bean AuthenticationManagerResolver<HttpServletRequest>
                                    multiTenantAuthMgr() {...}

                                AuthenticationManager jwt() {...}
                                AuthenticationManager opaque() {...}
                            }
                        
https://github.com/spring-projects/spring-security/issues/5351
https://github.com/spring-projects/spring-security/issues/6727

Use symmetric keys with JwtDecoder


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                              @Value("${spring.security.oauth2.resourceserver.
                                            jwt.key-value}") RSAPublicKey key;

                              @Override protected void configure(HttpSecurity http) {
                                http.oauth2ResourceServer().jwt().decoder(jwtDecoder());
                              }

                              @Bean JwtDecoder jwtDecoder() throws Exception {
                                  return NimbusJwtDecoder.
                                          withPublicKey(this.key).build();
                              }
                            }
                        
https://github.com/spring-projects/spring-security/issues/5465

JWT Flow API in Test Support


                            public class OAuth2ResourceServerTest {

                                @Test
                                public void testRequestPostProcessor() {
                                  mockMvc.perform(get("/message")
                                  .with(mockAccessToken().scope("message:read")))
                                  .andExpect(status().isOk())

                                  mockMvc.perform(get("/")
                                  .with(jwt().claim(SUB, "the-subject")))
                                  .andExpect(status().isOk())
                                }
                            }
                        
https://github.com/spring-projects/spring-security/issues/6634

Spring Security 5.3

Support OAuth 2.0 Authorization Server:

  • OAuth 2.0 Authorization Code Grant
  • OpenID Connect 1.0 (Authorization Code Flow)
  • PKCE
  • OAuth 2.0 Client Credentials Grant
  • JWT Access Token format
  • JWK Set Endpoint
  • Opaque Access Token format
  • OAuth 2.0 Token Revocation

Spring Security 5.3.0 GitHub Issues

Book References

Q&A

https://www.novatec-gmbh.de
https://blog.novatec-gmbh.de
andreas.falk@novatec-gmbh.de
Twitter: @andifalk

Online References

All images used are from Pixabay and are published under Creative Commons CC0 license.

All used logos are trademarks of respective companies