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

feat(jans-auth-server): Token Status List support #8620

Merged
merged 67 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
9c1b30a
chore(jans-auth-server): renamed OXAUTH_UMA_TICKET -> UMA_TICKET
yuriyz May 31, 2024
eb1340f
feat(jans-auth-server): Token Status List support
yuriyz May 31, 2024
d32bca8
fix(jans-auth-server): corrected requestContext and azd decoding
yuriyz May 31, 2024
d5b3ba9
feat(jans-auth-server): added token status list endpoint and status c…
yuriyz Jun 5, 2024
3987f87
feat(jans-auth): new cluster beans and services
yurem Jun 6, 2024
b9c5f3d
feat(jans-auth-server): added head index to list
yuriyz Jun 6, 2024
e79d463
Merge remote-tracking branch 'remotes/origin/token_list_changes' into…
yuriyz Jun 7, 2024
a1acf85
feat(jans-auth): move beans to core model
yurem Jun 7, 2024
ff7a3f9
feat(jans-auth): add index range to TokenPool
yurem Jun 7, 2024
f66c254
Merge branch 'main' into jans-auth-server-8562
yuriyz Jun 7, 2024
e8c6962
feat(jans-auth-server): added application/statuslist+json support
yuriyz Jun 7, 2024
9fc9e89
feat(jans-auth): add methods to allocate/release TokenPool
yurem Jun 7, 2024
2bb825c
feat(jans-auth): add methods to allocate/release TokenPool
yurem Jun 7, 2024
83f36ce
feat(jans-auth): fix TokenPool sort
yurem Jun 7, 2024
723ce03
feat(jans-auth): implement method to get nextIndex for token
yurem Jun 7, 2024
607cb03
feat(jans-auth): implement method to get nextIndex for token
yurem Jun 7, 2024
78bcd84
feat(jans-auth): instead of using token list status use expiration date
yurem Jun 7, 2024
63ab6b6
fix(jans-auth-server): fixed index during list joins and npe on nextI…
yuriyz Jun 7, 2024
80d0efd
Merge remote-tracking branch 'origin/jans-auth-server-8562' into jans…
yuriyz Jun 7, 2024
47b5f9b
feat(jans-auth-server): populate statusListIndex in access and id tokens
yuriyz Jun 7, 2024
5a48866
feat(jans-auth): add ClusterNode services
yurem Jun 10, 2024
4a573da
feat(jans-auth): add node base dn
yurem Jun 10, 2024
3501d12
feat(jans-auth-server): added status list update on revoke
yuriyz Jun 10, 2024
e54e82d
Merge remote-tracking branch 'origin/jans-auth-server-8562' into jans…
yuriyz Jun 10, 2024
192c3fc
fix after merge
yuriyz Jun 10, 2024
fce9bb4
feat(jans-auth): add schema for new entries
yurem Jun 11, 2024
408b7e4
feat(jans-auth): fix allocate
yurem Jun 11, 2024
8ffef42
feat(jans-auth): fix cluster nodes expiration
yurem Jun 11, 2024
2c48d79
merged main
yuriyz Jun 12, 2024
8be4f18
feat(jans-auth-server): added status list as jwt support
yuriyz Jun 12, 2024
f324c8d
feat(jans-auth): Deprecate TokenPoolStatus
yurem Jun 13, 2024
c86dd7e
feat(jans-auth): implement updateWithLock for concurent lock on revoke
yurem Jun 13, 2024
53e5c3a
feat(jans-auth-server): use updateWithLock during status update index
yuriyz Jun 13, 2024
e3cf9d9
feat(jans-auth-server): update status list on token revoke in separat…
yuriyz Jun 13, 2024
84e6d79
feat(jans-auth-server): renamed TokenPool -> StatusTokenPool, TokenPo…
yuriyz Jun 14, 2024
c066c3b
feat(jans-auth-server): removed token head index (we are using status…
yuriyz Jun 18, 2024
39c16ff
feat(jans-auth-server): added status list to swagger
yuriyz Jun 18, 2024
3a36b83
feat(jans-auth-server): added ou=node,o=jans to config
yuriyz Jun 18, 2024
46d9abc
feat(jans-auth-server): throw configuration exception if node baseDn …
yuriyz Jun 18, 2024
f1d4caf
feat(jans-auth-server): set status_list feature flag enabled by default
yuriyz Jun 19, 2024
bd4018c
fix(jans-auth-server): fixed node allocation
yuriyz Jun 19, 2024
214a489
fix(jans-auth-server): corrected bug in getClusterNodeLast
yuriyz Jun 19, 2024
3e7e322
feat(jans-auth-server): keep lockKey static and save in jansNode afte…
yuriyz Jun 19, 2024
c763ed9
fix(jans-auth-server): different fixes for cluster node management
yuriyz Jun 20, 2024
a58599e
fix(jans-auth-server): fixed allocation of status index pools
yuriyz Jun 20, 2024
44fb548
chore(jans-auth-server): added more logs for status index pool alloca…
yuriyz Jun 21, 2024
1f35103
feat(jans-auth): igore timezone when DB is PostgresSQL
yurem Jun 21, 2024
7a18504
feat(jans-auth): fetch all node entries if DB is LDAP
yurem Jun 24, 2024
1719b72
feat(jans-auth-server): added status list client
yuriyz Jun 24, 2024
11b0fbe
fix(jans-auth-server): fixed pool allocation
yuriyz Jun 24, 2024
3445a31
chore(jans-auth-server): renamed endpoint /token_status_list -> /stat…
yuriyz Jun 24, 2024
7180494
feat(jans-orm): resovle bean property name with AttributeName #8773
yurem Jun 24, 2024
36a453e
chore(jans-auth-server): renamed token_status_list -> status_list
yuriyz Jun 25, 2024
17b1431
chore(jans-auth-server): token statuses VALID - 0, INVALID - 1
yuriyz Jun 25, 2024
d5b2e82
chore(jans-auth-server): moved status list to model for re-using
yuriyz Jun 25, 2024
0a1842c
feat(jans-auth-server): added batch index update and fixed concurrent…
yuriyz Jun 26, 2024
ccf2306
feat(jans-auth-server): use new index update method in existing revok…
yuriyz Jun 26, 2024
a143dd0
fix(jans-auth-server): fixed status pool index joining
yuriyz Jun 27, 2024
6ca1e80
chore(jans-auth-server): code improvements
yuriyz Jun 27, 2024
da5f7bb
test(jans-auth-server): added full integration test for status list
yuriyz Jun 28, 2024
2148d90
test(jans-auth-server): added test for CN case
yuriyz Jun 28, 2024
c173c8d
feat(jans-auth-server): mark indexes which we are about to re-use as …
yuriyz Jun 28, 2024
f66b3a7
merged main
yuriyz Jun 28, 2024
e2d73a8
code re-format
yuriyz Jun 28, 2024
14d5dec
docs(config-api): regenerating config swagger api
pujavs Jun 28, 2024
adc3c4a
Merge branch 'main' into jans-auth-server-8562
yuriyz Jun 28, 2024
799831e
Merge branch 'main' into jans-auth-server-8562
moabu Jun 28, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,24 @@
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

import io.jans.agama.antlr.AuthnFlowLexer;
import io.jans.agama.antlr.AuthnFlowParser;
import io.jans.agama.dsl.error.SyntaxException;
import io.jans.agama.dsl.error.RecognitionErrorListener;
import io.jans.agama.dsl.error.SyntaxException;
import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.s9api.*;
import net.sf.saxon.sapling.SaplingDocument;
import org.antlr.v4.runtime.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.sapling.SaplingDocument;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Transpiler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public static void parse(String json, OpenIdConfigurationResponse response) {
response.setIssuer(jsonObj.optString(ISSUER, null));
response.setAuthorizationEndpoint(jsonObj.optString(AUTHORIZATION_ENDPOINT, null));
response.setAuthorizationChallengeEndpoint(jsonObj.optString(AUTHORIZATION_CHALLENGE_ENDPOINT, null));
response.setStatusListEndpoint(jsonObj.optString(STATUS_LIST_ENDPOINT, null));
response.setTokenEndpoint(jsonObj.optString(TOKEN_ENDPOINT, null));
response.setRevocationEndpoint(jsonObj.optString(REVOCATION_ENDPOINT, null));
response.setSessionRevocationEndpoint(jsonObj.optString(SESSION_REVOCATION_ENDPOINT, null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class OpenIdConfigurationResponse extends BaseResponse implements Seriali
private String issuer;
private String authorizationEndpoint;
private String authorizationChallengeEndpoint;
private String statusListEndpoint;
private String tokenEndpoint;
private String revocationEndpoint;
private String sessionRevocationEndpoint;
Expand Down Expand Up @@ -239,6 +240,24 @@ public void setAuthorizationChallengeEndpoint(String authorizationChallengeEndpo
this.authorizationChallengeEndpoint = authorizationChallengeEndpoint;
}

/**
* Gets status list
*
* @return status list
*/
public String getStatusListEndpoint() {
return statusListEndpoint;
}

/**
* Sets status list
*
* @param statusListEndpoint status list
*/
public void setStatusListEndpoint(String statusListEndpoint) {
this.statusListEndpoint = statusListEndpoint;
}

/**
* Returns the URL of the Token endpoint.
*
Expand Down Expand Up @@ -1300,6 +1319,7 @@ public String toString() {
"issuer='" + issuer + '\'' +
", authorizationEndpoint='" + authorizationEndpoint + '\'' +
", authorizationChallengeEndpoint='" + authorizationChallengeEndpoint + '\'' +
", statusListEndpoint='" + statusListEndpoint + '\'' +
", tokenEndpoint='" + tokenEndpoint + '\'' +
", revocationEndpoint='" + revocationEndpoint + '\'' +
", userInfoEndpoint='" + userInfoEndpoint + '\'' +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.jans.as.client;

import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.client.Invocation;
import org.apache.log4j.Logger;

/**
* @author Yuriy Z
*/
public class StatusListClient extends BaseClient<StatusListRequest, StatusListResponse> {

private static final Logger LOG = Logger.getLogger(StatusListClient.class);

/**
* Constructs a client for status list.
*
* @param url status list endpoint
*/
public StatusListClient(String url) {
super(url);
}

@Override
public String getHttpMethod() {
return HttpMethod.POST;
}

public StatusListResponse exec(StatusListRequest request) {
setRequest(request);
return exec();
}

public StatusListResponse exec() {
initClient();

Invocation.Builder clientRequest = webTarget.request();
applyCookies(clientRequest);

clientRequest.header("Content-Type", request.getContentType());

try {
clientResponse = clientRequest.buildGet().invoke();

final StatusListResponse response = new StatusListResponse(clientResponse);
setResponse(response);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
} finally {
closeConnection();
}

return getResponse();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.jans.as.client;

import io.jans.as.model.config.Constants;

/**
* @author Yuriy Z
*/
public class StatusListRequest extends BaseRequest {

public StatusListRequest() {
setContentType(Constants.CONTENT_TYPE_STATUSLIST_JSON);
}

@Override
public String getQueryString() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package io.jans.as.client;

import io.jans.as.model.config.Constants;
import io.jans.as.model.jwt.Jwt;
import io.jans.as.model.session.EndSessionErrorResponseType;
import io.jans.model.tokenstatus.StatusList;
import jakarta.ws.rs.core.Response;
import org.json.JSONObject;

import java.io.IOException;

/**
* @author Yuriy Z
*/
public class StatusListResponse extends BaseResponseWithErrors<EndSessionErrorResponseType> {

private String lst;
private int bits;
private Jwt jwt;

public StatusListResponse() {
}

public StatusListResponse(Response clientResponse) {
super(clientResponse);
injectData(clientResponse);
}

public StatusList getStatusList() throws IOException {
return StatusList.fromEncoded(lst, bits);
}

@Override
public EndSessionErrorResponseType fromString(String params) {
return EndSessionErrorResponseType.fromString(params);
}

public void injectData(Response clientResponse) {
injectErrorIfExistSilently(entity);
if (getErrorType() != null) {
return;
}

if (clientResponse.getStatus() != 200) {
return;
}

final String contentType = clientResponse.getHeaderString("Content-Type");
if (Constants.CONTENT_TYPE_STATUSLIST_JWT.equalsIgnoreCase(contentType)) {
jwt = Jwt.parseSilently(entity);
if (jwt != null) {
final JSONObject statusList = jwt.getClaims().getClaimAsJSON("status_list");
lst = statusList.getString("lst");
bits = statusList.getInt("bits");
}
} else if (Constants.CONTENT_TYPE_STATUSLIST_JSON.equalsIgnoreCase(contentType)) {
final JSONObject json = new JSONObject(entity);
final JSONObject statusList = json.getJSONObject("status_list");
lst = statusList.getString("lst");
bits = statusList.getInt("bits");
} else {
throw new UnsupportedOperationException("Unable to recognize content-type: " + contentType);
}
}

public String getLst() {
return lst;
}

public void setLst(String lst) {
this.lst = lst;
}

public int getBits() {
return bits;
}

public void setBits(int bits) {
this.bits = bits;
}

public Jwt getJwt() {
return jwt;
}

public void setJwt(Jwt jwt) {
this.jwt = jwt;
}

@Override
public String toString() {
return "StatusListResponse{" +
"lst='" + lst + '\'' +
", bits=" + bits +
", jwt=" + jwt +
"} " + super.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public abstract class BaseTest {
protected String gluuConfigurationEndpoint;
protected String tokenEndpoint;
protected String tokenRevocationEndpoint;
protected String statusListEndpoint;
protected String userInfoEndpoint;
protected String clientInfoEndpoint;
protected String checkSessionIFrame;
Expand Down Expand Up @@ -304,6 +305,14 @@ public void setAuthorizationChallengeEndpoint(String authorizationChallengeEndpo
this.authorizationChallengeEndpoint = authorizationChallengeEndpoint;
}

public String getStatusListEndpoint() {
return statusListEndpoint;
}

public void setStatusListEndpoint(String statusListEndpoint) {
this.statusListEndpoint = statusListEndpoint;
}

public String getTokenEndpoint() {
return tokenEndpoint;
}
Expand Down Expand Up @@ -1000,6 +1009,7 @@ public void discovery(ITestContext context) throws Exception {

authorizationEndpoint = response.getAuthorizationEndpoint();
authorizationChallengeEndpoint = response.getAuthorizationChallengeEndpoint();
statusListEndpoint = response.getStatusListEndpoint();
tokenEndpoint = response.getTokenEndpoint();
tokenRevocationEndpoint = response.getRevocationEndpoint();
userInfoEndpoint = response.getUserInfoEndpoint();
Expand All @@ -1024,6 +1034,7 @@ public void discovery(ITestContext context) throws Exception {

authorizationEndpoint = context.getCurrentXmlTest().getParameter("authorizationEndpoint");
authorizationChallengeEndpoint = context.getCurrentXmlTest().getParameter("authorizationChallengeEndpoint");
statusListEndpoint = context.getCurrentXmlTest().getParameter("statusListEndpoint");
tokenEndpoint = context.getCurrentXmlTest().getParameter("tokenEndpoint");
tokenRevocationEndpoint = context.getCurrentXmlTest().getParameter("tokenRevocationEndpoint");
userInfoEndpoint = context.getCurrentXmlTest().getParameter("userInfoEndpoint");
Expand Down
Loading