eclipse / microprofile-jwt-auth Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Currently, the generated javadoc for JWT has the Description field running together. I think a simple re-format of the package-info.java files would make this more readable.
The generated Description for the auth package looks like this:
Metadata for JWT RBAC for Microprofile This package contains supporting metadata classes: LoginConfig: an annotation that is used by a JAX-RS Application to define the authentication method and associated security realm.
And, the generated Description for the jwt package looks like this:
Interoperable JWT RBAC for Microprofile This package contains the primary interfaces and support classes for the JSON Web Tokens(JWT) for role based access control(RBAC) of MicroProfile microservice endpoints.
The current usage of Claim allows for an ambiguity:
@Inject
@Claim(name="myname",standard=Claims.sub)
private String myClaim;
In this situation, which claim should be searched for, or is there an error thrown?
We should define the behavior of the static javax.security.auth.Subject#getSubject() in the context of a secured endpoint that is utilizing MP-JWT authentication.
The MP-JWT spec 1.0 currently states in 7.1.1:
An MP-JWT implementation must support the injection of the currently authenticated caller as a
JsonWebToken with @RequestScoped scoping
However, a caller can logout in the midst of a request (i.e. by calling HttpServletRequest#logout
), and even login again (i.e. by calling HttpServletRequest#authenticate
or SecurityContext#authenticate
).
An @RequestScoped
JsonWebToken would have to be destroyed immediately after a logout in the middle of a request, but this requirement is not clear and the TCK does not seem to test for this. This runs the risk that some implementations will keep using the JsonWebToken to represent a caller, which is currently not the actual authenticated caller anymore.
Looking between the spec and the tck, its not clear to me what the actual list of types supported. If you look, the MP config spec lists this as a finite way, as well as how to register custom types.
Define the requirements for aligning MP-JWT authentication with JSR 375.
Some of the tests, e.g., RolesAllowedTest#callEchoNoAuth() do not have a @RunAsClient to execute on the client, and this is causing a requirement for test classes to be included in the WebArchive. This is an error in the test definition as all tests should be running as simple JAX-RS clients outside of the container runtime.
We had a discussion and decided that there is no reason to support both a roles and a groups claim as if a container could configure or default to a one-to-one mapping between IDP groups and application roles, the groups claim could satisfy all RBAC requirements.
In some cases Arquillian generates trailing / when injecting base URL with @ArquillianResource
.
toURL(Servlet servlet)
generates trailing / and toURL(HTTPContext context)
does not.
This represents a problem in almost all tests, beacuse they contain something similar to:
String uri = baseURL.toExternalForm() + "/endp/verifyInjectedIssuer";
When trailing / is present the uri
is set to something like http://host:port//endp/verifyInjectedIssuer
(note the two slashes between port
and endp
), which yields a 404 when queried and fails the test.
Don't rely on the full Java EE API, not all vendors will provide it.
In reviewing the current tck against WFSwarm I noticed that the org.eclipse.microprofile.jwt.tck.container.jaxrs.PrimitiveInjectionTest is not included in the tck/tck-base-suite.xml and tck/README.adoc, so it is likely that most runtimes have not validated this set of tests. When running against WFSwarm I do see that handling of injection of a claim like aud as a Set<String>
fails:
@Inject
@Claim("aud")
private Set<String> aud;
Hence there is likely a portability issue for injection of MP-JWT 1.0 primitive types.
@arjantijms suggested: one point for discussion might be pre-emptive authentication, i.e. when the caller sends a JWT token to a non-protected resource. The system can easily authenticate the caller as well then, but the spec seems to be written (and the TCK only tests for) the case when a protected resource is accessed.
Would like to see if we can have interoperable encrypted JWT, maybe some minimum support requirement similar to OIDC, http://openid.net/specs/openid-connect-core-1_0.html#Encryption
JWE: https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-40
After further review of the JSR-375 proposed final draft section 3.2.2. Retrieving Caller Information, as well as discussions with @chunlong, it is not appropriate for the JWTPrincipal#getGroups() method to be doing any mapping as other authorization modules and identity store may existing to handle this. The JWTPrincipal#getGroups() should just be returning the names of the groups in the "groups" claim grant if it exists, and empty set otherwise.
Just a gentle reminder that since this component has not used the updated release process yet, you will need updates to your spec's pom.xml file for proper generation of the pdf and html. We found a couple of hiccups with components during the MP 1.3 release, so I'm creating a couple of Issues as reminders. You can reference the Config component as an example of proper usage.
While there is nothing wrong with Nimbus Jose JWT, it is quite intrusive bringing its own JSON processing library (minidev). The KumuluzEE implementation uses auth0 java-jwt and e.g.:
JWTPrincipal demonstrates, Auth0 works perfectly fine with the JSON-P instead of its own library.
While writing a MP-JWT, I realized when I was investigating TCK failures that many JUnit assertions were swapped out.
I have created a PR I'll submit shortly with all the issues I pointed out.
According to the spec, 'aud' claim is required.
A same type of test as for issuer should be foreseen.
Hi,
Some files like beans.xml or arquillian.xml don't have the same header as the Java source files. Is that desire?
Should I create a PR for it?
Thanks
Jean-Louis
Was trying to figure out the remaining TCK issues in Hammock. I found that AppScopedTest
isn't working.
It doesn't extend from Arquillian
so it's not a valid CDI test, the CDI container never boots.
We have no tests that show an @ApplicationScoped
bean using @Claim ClaimValue
injection.
This is supported and should be tested
Apparently we need a site.yaml file to integrate with the Eclipse website?
https://github.com/eclipse/microprofile-fault-tolerance/blob/master/site.yaml
specific vendor tooling should not be required to use MicroProfile
Through the entire TCK, the expected
and actual
outcomes in an assertion are swapped.
E.g. see
Assert.assertEquals(HttpURLConnection.HTTP_OK, response.getStatus());
The first parameter should be the actual outcome, while the second should be the expected one. See
But as can be seen, the TCK reverses that.
As a result, output is now printed as:
ServletTest>Arquillian.run:164->getServletPrincipalClass:101 expected [500] but found [200]
This is clearly not correct. 200 is expected while 500 is the actual outcome in the example.
https://github.com/eclipse/microprofile-jwt-auth/tree/master/tck#tck-resource-files-and-information lists a bunch of resources provided. I'm attempting to make InvalidTokenTest
pass. When I enable token validation, since I'm using Nimbus Jose, I need to build a JWKSet. Its not clear how to translate the resources you're providing into that JWKSet based on the instructions available.
The JAX-RS client used in the tests does not register any providers. I believe you may be relying on resteasy specific behavior where providers are automatically registered. However, I don't believe that's a requirement of the JAX-RS Client API. Don't forget that since your tests run as client, they are always running outside the server.
need to add bnd.bnd to export the packages and also use the latest bnd plugin
I have an issue with the endpoints listed in the TCK.
If I look at UnsecuredPingEndpoint
, ClaimValueInjectionEndpoint
etc they lack a bean defining annotation. As a result, these classes are not necessarily CDI managed beans.
There's two ways to solve this.
beans.xml
that includes bean-discovery-mode="all"
@RequestScoped
or @Dependent
to each class.Note: this is an issue for Hammock, since Hammock is based on SE mode of CDI, which uses slightly different discovery rules.
I suspect that the Claim qualifier should be nonbinding. https://docs.jboss.org/cdi/api/1.0-SP2/javax/enterprise/util/Nonbinding.html
Basically, the current impl requires registering beans of each claim type to satisfy injection points. By making the attributes nonbinding, you can satisfy in a single producer method.
The api/pom.xml is currently missing the source jar generation.
All of our tests that result in a positive injection use @Claim(value=*)
We had a similar issue on the JMS spec, and it leads to a potentially much more complex implementation
In this section, its declared that we need to support injection of either RequestScoped or Dependent scoped identity. Is dependent really appropriate here? What is the use case?
I would prefer to see request scoped only, unless there's some specific need.
"MP-JWT implementation are required to throw a DeploymentException when detecting the ambiguous use of a @claim qualifier that includes inconsistent non-default values for both the value and standard elements as is the case shown here:
> @ApplicationScoped
> public class MyEndpoint {
> @Inject
> @Claim(value="exp", standard=Claims.iat)
> private Long timeClaim;
> ...
> }
Do you mean value and standard cannot be used together?
Currently the getOtherClaim(String) and getOtherClaimNames() methods only deal with the non-required claims. It has been suggested for the consistency, these method be general accessors for any claim in the JWT, including the required claims, and that the required claim names have constants in the interface.
I have the following configuration in place that runs the test suites.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<dependenciesToScan>
<dependency>org.eclipse.microprofile.config:microprofile-config-tck</dependency>
<dependency>org.eclipse.microprofile.health:microprofile-health-tck</dependency>
<dependency>org.eclipse.microprofile.jwt:microprofile-jwt-auth-tck</dependency>
</dependenciesToScan>
<excludes>
<exclude>org.eclipse.microprofile.config.tck.ConfigProviderTest</exclude>
<exclude>org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest</exclude>
<exclude>org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest</exclude>
</excludes>
<systemPropertyVariables>
<org.apache.geronimo.config.configsource.SystemPropertyConfigSource.copy>false</org.apache.geronimo.config.configsource.SystemPropertyConfigSource.copy>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
I added JWT to the tests to see what happens. It doesn't seem to scan anything though. Are the tests ending up in the dependency?
As pointed out in this thread:
https://groups.google.com/forum/#!topic/microprofile/BJO50mFZd8w
we should hava a TCK test for both injection of the JsonWebToken interface as well as the java.security.Principal superinterface to ensure both are handled.
Claim is a CDI qualifier annotation, of which you need to have an annotation literal in order to do programmatic lookup via the bean manager and/or CDI.current().select()
.
CDI 2.0 started a convention of adding literal instances and literal builders to the core and strongly related annotations. See http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#built_in_annotation_literals
I think it would be beneficial to add this to the Claim annotation too for a next version of JWT-ATH.
It seems weird to me that for TCK purposes only we have to implement a ITokenParser
. Why not just put this class in the API and look it up via CDI injection? End users may find this useful as well.
There is no license "ASLv2" remove references to it.
Review what changes would be needed to support the use of JSON-B with JsonWebToken and its claim values.
For better reuse in many use cases (beyond whats defined in MP) it would be good if Claim did not specify a target, which would allow implementations more freedom on where users could put the claim.
Currently following implementation supports the MP-JWT but issuer and public key configuration way is bit different in each implementation. It would be great, if it can be configured in vendor-neutral way e.g using MP-Config etc.
issuer - defined in "payara-mp-jwt.properties" which is placed in the classpath root of the application archive
public key - the file "publicKey.pem" which is also placed in the classpath root of the application archive
issuer - defined in the "mpJwt" tag in "server.xml" which in the placed inside the installed Liberty: [install dir]/wlp/usr/servers/defaultServer/server.xml
public key - the file "key.jks" which in the placed inside the installed Liberty: [install dir]/wlp/usr/servers/defaultServer/resources/security/key.jks
issuer - defined in "project-default.yml" which is placed in the classpath root of the application archive. This also configures the security system (security domain in JBoss terms) such that all artifacts to support MP-Auth JWT are installed
public key - the file "MP-JWT-SIGNER" which is placed in the classpath's META-INF of the application archive.
Ref : https://github.com/javaee-samples/microprofile1.2-samples/tree/master/jwt-auth
The current TCK seems to assume that you're using Wildfly Swarm or Weld SE. We should only be providing the tests in the TCK, and allowing the vendors to test with these tests.
There is a desire to define the use of a standard cookie name,value for interop between applications as described in:
https://blog.angular-university.io/angular-jwt-authentication/
and MP microservices.
Group ID should be in the format of org.eclipse.microprofile.jwt
(or maybe .jwt.auth
?). Please fix the group Ids to match. Please also fix the artifact Ids to line up with other specs.
I see the TCK has the notion of mapped roles. I thought I had it until I saw this test:
/**
* This endpoint requires a role that is mapped to the group1 role
* @return principal name
*/
@GET
@Path("/needsGroup1Mapping")
@RolesAllowed("Group1MappedRole")
public String needsGroup1Mapping(@Context SecurityContext sec) {
Principal user = sec.getUserPrincipal();
sec.isUserInRole("group1");
return user.getName();
}
I don't see any roles mentioned in the JWT called Group1MappedRole
so I have no idea how this role is mapped to the user. Also, for the scope of processing roles, I'm ignoring the object customObject
is that correct?
I have been implementing MP-JWT in TomEE.
And it's unclear to me where to use @LoginConfig.
I have assumed it can only be used to qualify a JAX RS Application.
It seems that Swarm did the same call (not sure though).
I see no problem technically to use @LoginConfig on a single JAX RS Resource.
What do you think?
Since the primary programmatic injection/lookup interface in CDI is the javax.enterprise.inject.Instance extension of javax.inject.Provider, we should be testing both in the org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionEndpoint
The MP-JWT TCK used the following construct:
@HttpConstraint(rolesAllowed={"Tester"})
@WebServlet("/ServiceServlet/*")
public class ServiceServlet extends HttpServlet {
This however can not work according to the Servlet spec; @HttpConstraint is supposed to appear within a @ServletSecurity annotation, and not be used on its own.
See:
Based on discussions around wanting to limit dependencies on servlet metadata descriptors, we decided a LoginConfig annotation that includes equivalent information would be the way to address this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.