Back to published notes

Public note

Understanding OAuth2 vs OpenID Connect Through Solace Message VPN Roles

AI summary

The article distinguishes between OAuth2 and OpenID Connect (OIDC) in Solace Message VPN roles, explaining 'client' mode as identity-focused authentication and 'resource-server' mode as permission-based authorization.

AI tags
authenticationauthorizationoauth2openidconnectsolacemessagevpn

Introduction

One of the most confusing parts of OAuth2 and OpenID Connect (OIDC) is understanding the difference between:

  • Authentication
  • Authorization
  • OAuth Client
  • Resource Server
  • ID Token
  • Access Token

This confusion becomes even more noticeable when reading the Solace Message VPN OAuth documentation because Solace supports two OAuth roles:

  • client
  • resource-server

At first glance, both modes appear identical because:

External client -> sends token -> Solace

However, the semantic meaning of the token and the validation behavior are very different.

This article explains those differences in detail.


Core Concept

The biggest misunderstanding usually comes from assuming:

"If a server validates a token, it must always be a Resource Server."

That is not always true.

The real distinction is:

ModeMain Concern
clientWho is the user? (Authentication)
resource-serverWhat is this token allowed to do? (Authorization)

OAuth2 vs OpenID Connect

Before understanding Solace roles, we must separate OAuth2 from OpenID Connect.


OAuth2

OAuth2 is fundamentally an authorization protocol.

Its primary concern is:

What is this application allowed to access?

The main artifact is:

Access Token

Example:

"This application may publish messages."

Typical access-token claims:

{
  "scope": "publish subscribe",
  "aud": "solace"
}

OAuth2 focuses on permissions.


OpenID Connect (OIDC)

OIDC is an authentication layer built on top of OAuth2.

Its primary concern is:

Who is this user?

The main artifact is:

ID Token

Example:

"This user is enum@company.com"

Typical ID-token claims:

{
  "sub": "user-123",
  "email": "enum@company.com",
  "name": "Enum"
}

OIDC focuses on identity.


Why the Solace Documentation Feels Confusing

The Solace documentation section is titled:

Client Authentication

not:

Authorization

This feels strange because OAuth2 is normally associated with authorization.

The reason is:

Solace treats broker connection acceptance as an authentication problem.

In other words:

"Should this client be allowed to CONNECT to the broker?"

For a messaging broker, token validation happens during connection establishment.

Therefore:

  • identity checks
  • token validation
  • permission validation

all happen during the CONNECT phase.


Solace OAuth Roles

Solace Message VPN supports:

  • oauth-role client
  • oauth-role resource-server

Both modes allow external clients to bring tokens.

However, the meaning of the token differs.


Resource Server Mode

Main Idea

In resource-server mode:

The token represents authorization.

The main question is:

"Is this token allowed to access this broker?"

Typical Flow

Diagram preview loading

Rendering Mermaid diagram from the saved markdown source.

sequenceDiagram
    participant App
    participant Solace
    participant IdP
    App->>Solace: Access Token
    Solace->>IdP: Introspection Request
    IdP-->>Solace: active=true
    Solace-->>App: Connection Accepted

Important Characteristics

FeatureBehavior
Token TypeAccess Token
Main FocusAuthorization
ValidationIntrospection or JWT validation
Scope ValidationImportant
Revocation AwarenessImportant

Typical Claims

{
  "scope": "publish subscribe",
  "aud": "solace",
  "exp": 1730000000
}

Client Mode

Main Idea

In client mode:

The token represents identity.

The main question is:

"Who is this user?"

This mode behaves more like OpenID Connect authentication.


Typical Flow

Diagram preview loading

Rendering Mermaid diagram from the saved markdown source.

sequenceDiagram
    participant Client
    participant Solace
    participant JWKS
    Client->>Solace: ID Token (JWT)
    Solace->>JWKS: Fetch Public Keys
    JWKS-->>Solace: Public Key
    Solace-->>Client: Connection Accepted

Important Characteristics

FeatureBehavior
Token TypeID Token
Main FocusAuthentication
ValidationJWT Signature Verification
Identity ClaimsImportant
Scope ValidationLess Important

JWT Structure

A JWT consists of three parts:

header.payload.signature

Example:

aaaaa.bbbbb.ccccc

Where:

PartMeaning
aaaaaBase64URL-encoded header
bbbbbBase64URL-encoded payload
cccccBase64URL-encoded signature

JWT Signature Verification

This is one of the most important concepts in OIDC.


Step 1: Extract Header and Payload

The verifier reconstructs:

signingInput =
    base64url(header)
    + "."
    + base64url(payload)

Example:

aaaaa.bbbbb

Step 2: Extract Signature

The third JWT part:

ccccc

is the signature.


Step 3: Find the Correct Public Key

The JWT header contains:

{
  "alg": "RS256",
  "kid": "abc123"
}

The verifier fetches the JWKS document:

{
  "keys": [
    {
      "kid": "abc123",
      "kty": "RSA"
    }
  ]
}

The verifier selects the key with:

kid == "abc123"

Step 4: Verify Signature

The Identity Provider originally created:

signature = Sign(privateKey, signingInput)

The verifier performs:

Verify(publicKey, signingInput, signature)

Meaning:

"Was this signature really created using the corresponding private key?"

Important Clarification

The public key does NOT decrypt the JWT payload.

JWT payloads are usually only Base64URL-encoded.

Anyone can decode them.

The public key is only used to verify:

Integrity + authenticity

Specifically:

  • The token was issued by the trusted Identity Provider
  • The payload was not modified

What Happens If Payload Changes?

Suppose the original payload was:

{
  "scope": "read"
}

An attacker changes it to:

{
  "scope": "admin"
}

Now:

header.payload

changes.

The existing signature no longer matches.

Verification fails.


Why kid Exists

Identity Providers rotate keys.

Therefore, multiple public keys may exist simultaneously.

The JWT header includes:

{
  "kid": "abc123"
}

so the verifier knows which key to use.


Authentication vs Authorization in Practice

This is the easiest way to think about it.


Client Mode

Equivalent to:

"Who are you?"

Like showing an employee badge.


Resource Server Mode

Equivalent to:

"What are you allowed to do?"

Like checking room-access permissions.


Why Both Can Still Use JWT

Modern JWTs often contain both:

  • identity information
  • authorization information

Example:

{
  "sub": "enum",
  "email": "enum@company.com",
  "scope": "publish"
}

Therefore the same JWT technology can support:

  • OIDC authentication
  • OAuth2 authorization

The difference is semantic interpretation.


Final Mental Model

oauth-role client

Solace asks:

"Who is this client?"

Focus:

  • identity
  • authenticated user
  • OIDC semantics

oauth-role resource-server

Solace asks:

"What is this token allowed to do?"

Focus:

  • scopes
  • permissions
  • authorization
  • token status

Final Summary Table

FeatureClient ModeResource Server Mode
Protocol SemanticsOpenID ConnectOAuth2
Main PurposeAuthenticationAuthorization
Main TokenID TokenAccess Token
Main ConcernIdentityPermissions
Typical ValidationJWT Signature ValidationIntrospection/JWT Validation
Uses JWKSYesOften
Uses IntrospectionRarelyFrequently
Checks scopeSometimesCommon
Checks sub/emailImportantLess Important

Conclusion

The key insight is:

Both modes may receive tokens from external clients.

However:

  • client mode interprets the token primarily as an identity assertion
  • resource-server mode interprets the token primarily as an authorization artifact

This distinction explains why the Solace documentation discusses OAuth inside a "Client Authentication" section even though OAuth2 is fundamentally an authorization framework.