Skip to content

Commit

Permalink
feat: switch rest-context token parser
Browse files Browse the repository at this point in the history
  • Loading branch information
andrejpetras committed Jan 22, 2024
1 parent 7e1da21 commit 435b4c3
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 347 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>io.github.onecx</groupId>
<artifactId>onecx-quarkus3-parent</artifactId>
<version>0.25.0</version>
<version>0.26.0</version>
</parent>

<artifactId>onecx-permission-svc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
import io.smallrye.config.WithName;

@StaticInitSafe
@ConfigMapping(prefix = "onecx.permission")
@ConfigMapping(prefix = "onecx.permission.token")
public interface TokenConfig {

@WithName("token.verified")
boolean tokenVerified();
@WithName("verified")
boolean verified();

@WithName("token.issuer.public-key-location.suffix")
String tokenPublicKeyLocationSuffix();
@WithName("issuer.public-key-location.suffix")
String publicKeyLocationSuffix();

@WithName("token.issuer.public-key-location.enabled")
boolean tokenPublicKeyEnabled();
@WithName("issuer.public-key-location.enabled")
boolean publicKeyEnabled();

@WithName("token.claim.separator")
Optional<String> tokenClaimSeparator();
@WithName("claim.separator")
Optional<String> claimSeparator();

@WithName("token.claim.path")
@WithName("claim.path")
@WithDefault("realm_access/roles")
String tokenClaimPath();
String claimPath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ClaimService {
@PostConstruct
@SuppressWarnings("java:S2696")
public void init() {
claimPath = splitClaimPath(config.tokenClaimPath());
claimPath = splitClaimPath(config.claimPath());
}

public String[] getClaimPath() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,45 @@
package io.github.onecx.permission.common.services;

import static io.github.onecx.permission.common.utils.TokenUtil.findClaimWithRoles;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.MalformedClaimException;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwx.JsonWebStructure;
import org.jose4j.lang.JoseException;
import org.tkit.quarkus.rs.context.token.TokenClaimUtility;
import org.tkit.quarkus.rs.context.token.TokenParserRequest;
import org.tkit.quarkus.rs.context.token.TokenParserService;

import io.github.onecx.permission.common.models.TokenConfig;
import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;
import io.smallrye.jwt.auth.principal.JWTParser;
import io.smallrye.jwt.auth.principal.ParseException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ApplicationScoped
public class TokenService {

@Inject
JWTAuthContextInfo authContextInfo;

@Inject
TokenConfig config;

@Inject
JWTParser parser;
ClaimService claimService;

@Inject
ClaimService claimService;
TokenParserService tokenParserService;

public List<String> getTokenRoles(String tokenData) {
try {
return getRoles(tokenData);
} catch (Exception ex) {
throw new TokenException("Error parsing principal token", ex);
}
}

private List<String> getRoles(String tokenData)
throws JoseException, InvalidJwtException, MalformedClaimException, ParseException {

var claimPath = claimService.getClaimPath();

if (config.tokenVerified()) {
var info = authContextInfo;

// get public key location from issuer URL
if (config.tokenPublicKeyEnabled()) {
var jws = (JsonWebSignature) JsonWebStructure.fromCompactSerialization(tokenData);
var jwtClaims = JwtClaims.parse(jws.getUnverifiedPayload());
var publicKeyLocation = jwtClaims.getIssuer() + config.tokenPublicKeyLocationSuffix();
info = new JWTAuthContextInfo(authContextInfo);
info.setPublicKeyLocation(publicKeyLocation);
}

var token = parser.parse(tokenData, info);
var first = token.getClaim(claimPath[0]);

return findClaimWithRoles(config, first, claimPath);
try {

} else {
var request = new TokenParserRequest(tokenData)
.verify(config.verified())
.issuerEnabled(config.publicKeyEnabled())
.issuerSuffix(config.publicKeyLocationSuffix());

var jws = (JsonWebSignature) JsonWebStructure.fromCompactSerialization(tokenData);
var permissionToken = tokenParserService.parseToken(request);
var path = claimService.getClaimPath();
return TokenClaimUtility.findClaimStringList(permissionToken, path, config.claimSeparator().orElse(" "));

var jwtClaims = JwtClaims.parse(jws.getUnverifiedPayload());
var first = jwtClaims.getClaimValue(claimPath[0]);
return findClaimWithRoles(config, first, claimPath);
} catch (Exception ex) {
throw new TokenException("Error parsing permission token", ex);
}
}

Expand Down

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/openapi/onecx-permission-internal-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ components:
type: object
required:
- description
- modificationCount
properties:
modificationCount:
format: int32
Expand Down Expand Up @@ -699,6 +700,8 @@ components:
type: string
UpdateRoleRequest:
type: object
required:
- modificationCount
properties:
modificationCount:
format: int32
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ quarkus.datasource.jdbc.min-size=10

quarkus.hibernate-orm.database.generation=validate
quarkus.hibernate-orm.multitenant=DISCRIMINATOR
quarkus.hibernate-orm.jdbc.timezone=UTC
quarkus.liquibase.migrate-at-start=true
quarkus.liquibase.validate-on-migrate=true

Expand Down Expand Up @@ -41,7 +42,6 @@ quarkus.test.integration-test-profile=test
%test.tkit.rs.context.tenant-id.mock.enabled=true
%test.tkit.rs.context.tenant-id.mock.default-tenant=default
%test.tkit.rs.context.tenant-id.mock.claim-org-id=orgId
%test.tkit.rs.context.tenant-id.mock.token-header-param=apm-principal-token
%test.tkit.rs.context.tenant-id.mock.data.org1=100
%test.tkit.rs.context.tenant-id.mock.data.org2=200
%test.tkit.rs.context.tenant-id.mock.data.i100=i100
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 435b4c3

Please sign in to comment.