Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Doc PR] - Helidon MP JWT Auth #4200 #4515

Merged
merged 2 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions docs/config/io_helidon_microprofile_jwt.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2022 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

///////////////////////////////////////////////////////////////////////////////

// MANUALLY CREATED DOC

:description: Configuration of io.helidon.microprofile.jwt
:keywords: helidon, config, io.helidon.health.HealthSupport.adoc
:basic-table-intro: The table below lists the configuration keys that configure io.helidon.microprofile.jwt.adoc

= JWT Configuration

// tag::config[]

== Configuration options
dalexandrov marked this conversation as resolved.
Show resolved Hide resolved


MicroProfile configuration options:
[cols="3,3,2,5"]

|===
|key |type |default value |description

|`mp.jwt.verify.publickey` |string |{nbsp} |The property allows the Public Verification Key text itself to be supplied as a string.
|`mp.jwt.verify.publickey.location` |string |{nbsp} | The property allows for an external or internal location of Public Verification Key to be specified. The value may be a relative path or a URL.
|`mp.jwt.verify.publickey.algorithm` |string |{nbsp} |The configuration property allows for specifying which Public Key Signature Algorithm is supported by the MP JWT endpoint. This property can be set to either `RS256` or `ES256`. Default value is `RS256`. Support for the other asymmetric signature algorithms such as `RS512`, `ES512` and others is optional.

|===

Optional configuration options:
[cols="3,3,2,5"]

|===
|key |type |default value |description

|`optional` |boolean |`false` |If set to `true`, failure to authenticate will return `ABSTAIN` result instead of `FAILURE`. This is
an important distinction when more than one provider is used
|`authenticate` |boolean |`true` |Whether to attempt authentication
|`propagate`|boolean |`true` |Whether to attempt identity propagation/JWT creation
|`principal-type`|string |`USER` |Whether we authenticate a user or a service (other option is SERVICE)
|`atn-token` |string |A group for configuring authentication of the request
|`atn-token.verify-signature`|boolean |`true` |Whether to verify signature in incoming JWT. If disabled, _ANY_ JWT will be accepted
|`atn-token.jwt-audience`|string |{nbsp} |Expected audience of the JWT. If not defined, any audience is accepted (and we may accept JWT not inteded for us)
|`atn-token.jwk.resource.*`|string |{nbsp} |Configuration of the JWK to obtain key(s) to validate signatures of inbound token. The JWK should contain public keys. This may be: jwk.resource.path, jwk.resource.resource-path, jwk.resource.url, jwk.resource.content-plain (actual JSON string), jwk.resource.content (base64)
|`atn-token.handler`|string |`Authorization` header with `bearer ` prefix |A handler configuration for inbound token - e.g. how to extract it
|`atn-token.handler.header`|string |{nbsp} |Name of a header the token is expected in
|`atn-token.handler.prefix`|string |{nbsp} |Prefix before the token value (optional)
|`atn-token.handler.regexp`|string |{nbsp} |Regular expression to obtain the token, first matching group is used (optional)
|`sign-token`|string |{nbsp} |A group for configuring outbound security
|`sign-token.jwk.resource.*` |{nbsp} |Configuration of the JWK to use when generating tokens (follows same rules as atn-token.jwk above), this JWK must contain private keys when using asymmetric ciphers
|`sign-token.jwt-issuer`|string |{nbsp} |When we issue a new token, this is the issuer to be placed into it (validated by target service)
|`sign-token.outbound`|string |{nbsp} |A group for configuring outbound rules (based on transport, host and.or path)
|`sign-token.outbound.*.name`|string |{nbsp} |A short descriptive name for configured target service(s)
|`sign-token.outbound.*.transports`|string |any |An array of transports this outbound matches (e.g. https)
|`sign-token.outbound.*.hosts`|string |any |An array of hosts this outbound matches, may use * as a wild-card (e.g. *.oracle.com)
|`sign-token.outbound.*.paths`|string |any |An array of paths on the host this outbound matches, may use * as a wild-card (e.g. /some/path/*)
|`sign-token.outbound.*.outbound-token`|string |`Authorization` header with `bearer ` prefix |Configuration of outbound token handler (same as atn-token.handler)
|`sign-token.outbound.*.outbound-token.format`|string |{nbsp} |Java text format for generating the value of outbound token header (e.g. "bearer %1$s")
|`sign-token.outbound.*.jwk-kid`|string |{nbsp} |If this key is defined, we are generating a new token, otherwise we propagate existing. Defines the key id of a key definition in the JWK file to use for signing the outbound token
|`sign-token.outbound.*.jwt-kid`|string |{nbsp} |A key to use in the generated JWT - this is for the other service to locate the verification key in their JWK
|`sign-token.outbound.*.jwt-audience`|string |{nbsp} |Audience this key is generated for (e.g. http://www.example.org/api/myService) - validated by the other service
|`sign-token.outbound.*.jwt-not-before-seconds`|string |`5` |Makes this key valid this amount of seconds into the past. Allows a certain time-skew for the generated token to be valid before current time (e.g. when we expect a certain misalignment of clocks)
|`sign-token.outbound.*.jwt-validity-seconds`|string |1 day |Token validity in seconds
|===

// end::config[]
121 changes: 115 additions & 6 deletions docs/mp/jwt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@
:rootdir: {docdir}/..
include::{rootdir}/includes/mp.adoc[]

== Contents

- <<Overview, Overview>>
- <<Maven Coordinates, Maven Coordinates>>
- <<Usage, Usage>>
- <<API, API>>
- <<Configuration, Configuration>>
- <<Examples, Examples>>
- <<Additional Information, Additional Information>>
- <<Reference, Reference>>

== Overview

JSON Web Tokens (JWT) are an open, industry standard https://datatracker.ietf.org/doc/html/rfc7519[(RFC 7519)] method for representing claims securely between two parties.

JSON Web Token defines a compact and self-contained way for securely transmitting information between parties as a JSON object. With JWT Auth you can integrate security features such as single sign on into your Helidon MP applications.
dalexandrov marked this conversation as resolved.
Show resolved Hide resolved


include::{rootdir}/includes/dependencies.adoc[]

[source,xml]
Expand All @@ -37,15 +55,12 @@ include::{rootdir}/includes/dependencies.adoc[]
</dependency>
----

== Overview
JSON Web Token (JWT) defines a compact and self-contained way for securely transmitting information between parties as a JSON object. With JWT Auth you can integrate security features such as single sign on into your Helidon MP applications.

== Next Steps
== Usage

The main configuration point for JWT Auth is a JAX-RS Application class.
As this class is discovered using CDI, it must have a bean defining annotation.

Example of an application that enables JWT-Auth (with minimal required annotations):
Minimal required setup is done using `@LoginConfig(authMethod = "MP-JWT")`:

[source,java]
----
Expand All @@ -55,6 +70,100 @@ public class ProtectedApplication extends Application{
}
----

Learn more about JWT authentication: +
== API

The following interfaces and annotations are used to work with JWT in Helidon MP:

* `JsonWebToken` - an interface used in CDI beans _(@RequestScoped)_ dependency injection to obtain the JWT of the currently executing caller.
* `@Claim` - an annotation used by CDI bean _(@RequestScoped)_ dependency injection to obtain individual claims from the caller’s JWT.
* `ClaimValue` - a proxy interface used with `@Claim` annotation to оbtain the value of a claim by calling `getValue()`.

== Configuration

include::{rootdir}/config/io_helidon_microprofile_jwt.adoc[leveloffset=+1,tag=config]

A configuration example in `microprofile-config.properties`:
[source, properties]
----
mp.jwt.verify.issuer=https://{PublicIssuerDomain}/oauth2/default
mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys
----

== Examples

[source, java]
----
@Path("/hello")
public class HelloResource {

@GET
@Produces(TEXT_PLAIN)
public String hello(@Context SecurityContext context) {
Optional<Principal> userPrincipal = context.userPrincipal();
return "Hello, " + userPrincipal.get().getName() + "!";
}
}
----

Do not forget to annotate the `HelloApplication` class to enable JWT:

[source, java]
----
@LoginConfig(authMethod = "MP-JWT")
@ApplicationScoped
public class HelloApplication extends Application {

@Override
public Set<Class<?>> getClasses() {
return Set.of(HelloResource.class);
}
}
----

Add the following configuration in `microprofile-config.properties`:

[source, properties]
----
mp.jwt.verify.issuer=https://{IssuerPublicDomain}/oauth2/default
mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys
----

Obtain the Security Token from external issuer:

[source, bash]
----
TOKEN=sdf4dDSWFcswdsffDSasEgv...
----

Run the application and execute an http request against it:
dalexandrov marked this conversation as resolved.
Show resolved Hide resolved

[source, bash]
----
curl -X GET -I -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello

----

The result should be:

[source, bash]
----
HTTP/1.1 200 OK
Date: 08.06.2022 10:33:47 EEST
connection: keep-alive
content-length: 28

Hello, secure@helidon.io!
----

which means that the request successfully passed authentication.

== Additional Information
m0mus marked this conversation as resolved.
Show resolved Hide resolved

Learn more about JWT authentication at: +
link:{microprofile-jwt-base-url}#_introduction[Eclipse MicroProfile Interoperable JWT RBAC]

== Reference

* {microprofile-jwt-spec-url}[MicroProfile JWT Auth Spec]
* https://github.com/eclipse/microprofile-jwt-auth[MicroProfile JWT Auth GitHub Repository]