Skip to content

Commit

Permalink
KNOX-3020 - Introducing the 'type' metadata for Knox Tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
smolnar82 committed Mar 14, 2024
1 parent 84999b8 commit c40c8bd
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ public abstract class AbstractJWTFilter implements Filter {
*/
public static final String JWT_EXPECTED_SIGALG = "jwt.expected.sigalg";
public static final String JWT_DEFAULT_SIGALG = "RS256";
public static final String TYPE = "type";
public static final String CLIENT_ID = "CLIENT_ID";

static JWTMessages log = MessagesFactory.get( JWTMessages.class );

Expand Down Expand Up @@ -302,22 +300,16 @@ protected Subject createSubjectFromToken(final JWT token) throws UnknownTokenExc

public Subject createSubjectFromTokenIdentifier(final String tokenId) throws UnknownTokenException {
TokenMetadata metadata = tokenStateService.getTokenMetadata(tokenId);
String username = null;
if (metadata != null) {
String type = metadata.getMetadata(TYPE);
// using tokenID and passcode as CLIENT_ID and CLIENT_SECRET will
// result in a metadata item called "type". If the value is set
// to CLIENT_ID then it will be assumed to be a CLIENT_ID and we
// will use the token id as the username. Since we don't know the
// token id until it is created, the username is always the same
// in the record. Using the token id makes it a unique username for
// audit and the like.
if (CLIENT_ID.equalsIgnoreCase(type)) {
username = tokenId;
}
else {
username = metadata.getUserName();
}
final String username = metadata.isClientId() ? tokenId : metadata.getUserName();

return createSubjectFromTokenData(username, null);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ private void saveToken(JWT token) {
final long issueTime = System.currentTimeMillis();
tokenStateService.addToken(tokenId, issueTime, token.getExpiresDate().getTime(), tokenStateService.getDefaultMaxLifetimeDuration());
final TokenMetadata tokenMetadata = new TokenMetadata(token.getSubject());
tokenMetadata.setKnoxSsoCookie(true);
tokenMetadata.markKnoxSsoCookie();
tokenMetadata.useTokenNow();
tokenStateService.addMetadata(tokenId, tokenMetadata);
LOGGER.storedToken(getTopologyName(), Tokens.getTokenDisplayText(token.toString()), Tokens.getTokenIDDisplayText(tokenId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ private void testLimitingTokensPerUser(int configuredLimit, int numberOfTokens,
final String tokenId = getTagValue(tokenResponse.getEntity().toString(), "token_id");
assertNotNull(tokenId);
final TokenMetadata tokenMetadata = new TokenMetadata(USER_NAME);
tokenMetadata.setKnoxSsoCookie(true);
tokenMetadata.markKnoxSsoCookie();
tss.addMetadata(tokenId, tokenMetadata);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public class TokenMetadata {
public static final String ENABLED = "enabled";
public static final String PASSCODE = "passcode";
public static final String CREATED_BY = "createdBy";
public static final String KNOX_SSO_COOKIE = "knoxSSOCookie";
public static final String LAST_USED_AT = "lastUsedAt";
private static final List<String> KNOWN_MD_NAMES = Arrays.asList(USER_NAME, COMMENT, ENABLED, PASSCODE, CREATED_BY, KNOX_SSO_COOKIE, LAST_USED_AT);
public static final String TYPE = "type";
private static final List<String> KNOWN_MD_NAMES = Arrays.asList(USER_NAME, COMMENT, ENABLED, PASSCODE, CREATED_BY, LAST_USED_AT, TYPE);

private final Map<String, String> metadataMap = new HashMap<>();

Expand All @@ -59,6 +59,7 @@ public TokenMetadata(String userName, String comment, boolean enabled) {
saveMetadata(USER_NAME, userName);
saveMetadata(COMMENT, comment);
setEnabled(enabled);
setType(TokenMetadataType.JWT);
}

private void saveMetadata(String key, String value) {
Expand Down Expand Up @@ -125,14 +126,6 @@ public String getCreatedBy() {
return getMetadata(CREATED_BY);
}

public void setKnoxSsoCookie(boolean knoxSsoCookie) {
saveMetadata(KNOX_SSO_COOKIE, String.valueOf(knoxSsoCookie));
}

public boolean isKnoxSsoCookie() {
return Boolean.parseBoolean(getMetadata(KNOX_SSO_COOKIE));
}

public void useTokenNow() {
saveMetadata(LAST_USED_AT, Instant.now().toString());
}
Expand All @@ -142,6 +135,28 @@ public Instant getLastUsedAt() {
return lastUsedAt == null ? null : Instant.parse(lastUsedAt);
}

public void setType(TokenMetadataType type) {
saveMetadata(TYPE, type.name());
}

public void markKnoxSsoCookie() {
setType(TokenMetadataType.KNOXSSO_COOKIE);
}

@JsonIgnore
public boolean isKnoxSsoCookie() {
return getType() == null ? false : TokenMetadataType.KNOXSSO_COOKIE == TokenMetadataType.valueOf(getType());
}

@JsonIgnore
public boolean isClientId() {
return getType() == null ? false : TokenMetadataType.CLIENT_ID == TokenMetadataType.valueOf(getType());
}

public String getType() {
return getMetadata(TYPE);
}

public String toJSON() {
return JsonUtils.renderAsJsonString(metadataMap);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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.
*/
package org.apache.knox.gateway.services.security.token;

public enum TokenMetadataType {

JWT, KNOXSSO_COOKIE, CLIENT_ID;

}
2 changes: 1 addition & 1 deletion knox-token-management-ui/token-management/app/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class Metadata {
enabled: boolean;
userName: string;
createdBy: string;
knoxSsoCookie: boolean;
type: string;
comment: string;
customMetadataMap: Map<string, string>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@
</mat-cell>
</ng-container>

<ng-container matColumnDef="knoxSso">
<mat-header-cell *matHeaderCellDef mat-sort-header="knoxSso" style="text-align: center; justify-content: center;">KnoxSSO</mat-header-cell>
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header="type" style="text-align: center; justify-content: center;">Type</mat-header-cell>
<mat-cell *matCellDef="let knoxToken" style="text-align: center; justify-content: center;">
<img *ngIf="isKnoxSsoCookie(knoxToken)" src="assets/green_checkmark.svg" style="height:20px; width:auto" />
<img *ngIf="!isKnoxSsoCookie(knoxToken)" src="assets/red_cross_circle.svg" style="height:20px; width:auto" />
<img src="assets/{{knoxToken.metadata.type}}.png" style="height:30px; width:auto" />
</mat-cell>
</ng-container>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class TokenManagementComponent implements OnInit {
selection = new SelectionModel<KnoxToken>(true, []);
allKnoxTokens: KnoxToken[];

displayedColumns = ['select', 'tokenId', 'issued', 'expires', 'userName', 'impersonated', 'knoxSso', 'comment', 'metadata', 'actions'];
displayedColumns = ['select', 'tokenId', 'issued', 'expires', 'userName', 'impersonated', 'type', 'comment', 'metadata', 'actions'];
@ViewChild('knoxTokensPaginator') paginator: MatPaginator;
@ViewChild('knoxTokensSort') sort: MatSort = new MatSort();

Expand Down Expand Up @@ -130,7 +130,7 @@ export class TokenManagementComponent implements OnInit {
}

private isDisabledKnoxSsoCookie(token: KnoxToken): boolean {
return token.metadata.knoxSsoCookie && !token.metadata.enabled;
return this.isKnoxSsoCookie(token) && !token.metadata.enabled;
}

private updateTokens(tokens: KnoxToken[]): void {
Expand Down Expand Up @@ -217,7 +217,7 @@ export class TokenManagementComponent implements OnInit {
}

isKnoxSsoCookie(knoxToken: KnoxToken): boolean {
return knoxToken.metadata.knoxSsoCookie;
return 'KNOXSSO_COOKIE' === knoxToken.metadata.type;
}

isDisabledKnoxSSoCookie(knoxToken: KnoxToken): boolean {
Expand Down Expand Up @@ -269,7 +269,7 @@ export class TokenManagementComponent implements OnInit {
}

private selectionHasZeroKnoxSsoCookie(): boolean {
return this.selection.selected.every(token => !token.metadata.knoxSsoCookie);
return this.selection.selected.every(token => !this.isKnoxSsoCookie(token));
}

private selectionHasZeroExpiredToken(): boolean {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c40c8bd

Please sign in to comment.