Skip to content

Commit

Permalink
feat(jans-auth-server): new endpoint for get jwt of ssa based on jti. (
Browse files Browse the repository at this point in the history
…#3724)

feat(docs): updated swagger for new endpoint get jwt of ssa, also added more documentation for scopes.
  • Loading branch information
Milton-Ch authored Jan 30, 2023
1 parent 82ed38e commit 7dcca94
Show file tree
Hide file tree
Showing 26 changed files with 943 additions and 245 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.as.client.ssa.jwtssa;

import io.jans.as.client.BaseClient;
import io.jans.as.model.config.Constants;
import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.client.Invocation.Builder;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;

public class SsaGetJwtClient extends BaseClient<SsaGetJwtRequest, SsaGetJwtResponse> {

private static final Logger log = Logger.getLogger(SsaGetJwtClient.class);

public SsaGetJwtClient(String url) {
super(url + "/jwt");
}

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

public SsaGetJwtResponse execGetJwtSsa(@NotNull String accessToken, @NotNull String jti) {
SsaGetJwtRequest ssaGetRequest = new SsaGetJwtRequest();
ssaGetRequest.setJti(jti);
ssaGetRequest.setAccessToken(accessToken);
setRequest(ssaGetRequest);
return exec();
}

public SsaGetJwtResponse exec() {
try {
initClient();
String uriWithParams = getUrl() + "?" + getRequest().getQueryString();
Builder clientRequest = resteasyClient.target(uriWithParams).request();
applyCookies(clientRequest);

clientRequest.header("Content-Type", request.getContentType());
if (StringUtils.isNotBlank(request.getAccessToken())) {
clientRequest.header(Constants.AUTHORIZATION, "Bearer ".concat(request.getAccessToken()));
}

clientResponse = clientRequest.build(getHttpMethod()).invoke();
final SsaGetJwtResponse res = new SsaGetJwtResponse(clientResponse);
res.injectDataFromJson();
setResponse(res);

} 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,49 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.as.client.ssa.jwtssa;

import io.jans.as.client.BaseRequest;
import io.jans.as.model.common.AuthorizationMethod;
import io.jans.as.model.ssa.SsaRequestParam;
import io.jans.as.model.util.QueryBuilder;
import jakarta.ws.rs.core.MediaType;

public class SsaGetJwtRequest extends BaseRequest {

private String jti;

private String accessToken;

public SsaGetJwtRequest() {
setContentType(MediaType.APPLICATION_JSON);
setMediaType(MediaType.APPLICATION_JSON);
setAuthorizationMethod(AuthorizationMethod.AUTHORIZATION_REQUEST_HEADER_FIELD);
}

public String getJti() {
return jti;
}

public void setJti(String jti) {
this.jti = jti;
}

public String getAccessToken() {
return accessToken;
}

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

@Override
public String getQueryString() {
QueryBuilder builder = QueryBuilder.instance();
builder.append(SsaRequestParam.JTI.getName(), jti);
return builder.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.as.client.ssa.jwtssa;

import io.jans.as.client.BaseResponseWithErrors;
import io.jans.as.model.ssa.SsaErrorResponseType;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

import static io.jans.as.model.ssa.SsaRequestParam.SSA;

public class SsaGetJwtResponse extends BaseResponseWithErrors<SsaErrorResponseType> {

private static final Logger log = Logger.getLogger(SsaGetJwtResponse.class);

private String ssa;

public SsaGetJwtResponse(Response clientResponse) {
super(clientResponse);
}

@Override
public SsaErrorResponseType fromString(String p_str) {
return SsaErrorResponseType.fromString(p_str);
}

public void injectDataFromJson() {
injectDataFromJson(entity);
}

@Override
public void injectDataFromJson(String json) {
if (StringUtils.isNotBlank(entity)) {
try {
JSONObject jsonObj = new JSONObject(entity);
if (jsonObj.has(SSA.getName())) {
ssa = jsonObj.getString(SSA.getName());
}
} catch (JSONException e) {
log.error("Error on inject data from json: " + e.getMessage(), e);
}
}
}

public String getSsa() {
return ssa;
}

public void setSsa(String ssa) {
this.ssa = ssa;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.jans.as.client.ssa.create.SsaCreateRequest;
import io.jans.as.client.ssa.create.SsaCreateResponse;
import io.jans.as.client.ssa.get.SsaGetResponse;
import io.jans.as.client.ssa.jwtssa.SsaGetJwtResponse;
import io.jans.as.model.exception.InvalidJwtException;
import io.jans.as.model.jwe.Jwe;
import io.jans.as.model.jwt.Jwt;
Expand Down Expand Up @@ -65,4 +66,8 @@ public static SsaCreateAssertBuilder ssaCreate(SsaCreateRequest request, SsaCrea
public static SsaGetAssertBuilder ssaGet(SsaGetResponse response) {
return new SsaGetAssertBuilder(response);
}

public static SsaGetJwtAssertBuilder ssaGetJwt(SsaGetJwtResponse response) {
return new SsaGetJwtAssertBuilder(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.jans.as.client.client.assertbuilders;

import io.jans.as.client.ssa.jwtssa.SsaGetJwtResponse;
import io.jans.as.model.jwt.Jwt;
import io.jans.as.model.jwt.JwtClaims;
import org.apache.http.HttpStatus;

import static io.jans.as.model.ssa.SsaRequestParam.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

public class SsaGetJwtAssertBuilder extends BaseAssertBuilder {

private final SsaGetJwtResponse response;
private int status;

public SsaGetJwtAssertBuilder(SsaGetJwtResponse response) {
this.response = response;
}

public SsaGetJwtAssertBuilder status(int status) {
this.status = status;
return this;
}

@Override
public void check() {
assertNotNull(response, "SsaGetJwtResponse is null");
assertEquals(response.getStatus(), status, "Unexpected HTTP status response: " + response.getStatus());
if (status == HttpStatus.SC_OK) {
assertNotNull(response.getEntity(), "The entity is null");
assertNotNull(response.getSsa(), "The ssa token is null");

Jwt jwt = Jwt.parseSilently(response.getSsa());
assertNotNull(jwt, "The jwt is null");
JwtClaims jwtClaims = jwt.getClaims();
assertNotNull(jwtClaims.getClaim(ORG_ID.getName()), "The org_id in jwt is null");
assertNotNull(jwtClaims.getClaim(SOFTWARE_ID.getName()), "The software_id in jwt is null");
assertNotNull(jwtClaims.getClaim(SOFTWARE_ROLES.getName()), "The software_roles in jwt is null");
assertNotNull(jwtClaims.getClaim(GRANT_TYPES.getName()), "The grant_types in jwt is null");

assertNotNull(jwtClaims.getClaim(JTI.getName()), "The jti in jwt is null");
assertNotNull(jwtClaims.getClaim(ISS.getName()), "The iss in jwt is null");
assertNotNull(jwtClaims.getClaim(IAT.getName()), "The iat in jwt is null");
assertNotNull(jwtClaims.getClaim(EXP.getName()), "The exp in jwt is null");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.as.client.ssa;

import io.jans.as.client.BaseTest;
import io.jans.as.client.RegisterResponse;
import io.jans.as.client.TokenResponse;
import io.jans.as.client.client.AssertBuilder;
import io.jans.as.client.ssa.create.SsaCreateResponse;
import io.jans.as.client.ssa.jwtssa.SsaGetJwtClient;
import io.jans.as.client.ssa.jwtssa.SsaGetJwtResponse;
import io.jans.as.model.common.GrantType;
import io.jans.as.model.common.ResponseType;
import io.jans.as.model.ssa.SsaScopeType;
import org.apache.http.HttpStatus;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.util.Collections;
import java.util.List;

public class SsaGetJwtTest extends BaseTest {

@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
public void getJwtSsaWithJtiValidResponseOkWithJwtSsa(final String redirectUris, final String sectorIdentifierUri) {
showTitle("getJwtSsaWithJtiValidResponseOkWithJwtSsa");
List<String> scopes = Collections.singletonList(SsaScopeType.SSA_ADMIN.getValue());

// Register client
RegisterResponse registerResponse = registerClient(redirectUris, Collections.singletonList(ResponseType.CODE),
Collections.singletonList(GrantType.CLIENT_CREDENTIALS), scopes, sectorIdentifierUri);
String clientId = registerResponse.getClientId();
String clientSecret = registerResponse.getClientSecret();

// Access token
TokenResponse tokenResponse = tokenClientCredentialsGrant(SsaScopeType.SSA_ADMIN.getValue(), clientId, clientSecret);
String accessToken = tokenResponse.getAccessToken();

// Create ssa
SsaCreateResponse ssaCreateResponse = createSsaWithDefaultValues(accessToken, null, null, Boolean.TRUE);
String jti = ssaCreateResponse.getJti();

// Get Jwt of SSA
SsaGetJwtClient ssaGetJwtClient = new SsaGetJwtClient(ssaEndpoint);
SsaGetJwtResponse ssaGetJwtResponse = ssaGetJwtClient.execGetJwtSsa(accessToken, jti);
showClient(ssaGetJwtClient);
AssertBuilder.ssaGetJwt(ssaGetJwtResponse).status(HttpStatus.SC_OK).check();
}

@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
public void getJwtSsaWithJtiWrongResponse422(final String redirectUris, final String sectorIdentifierUri) {
showTitle("getJwtSsaWithJtiWrongResponse422");
List<String> scopes = Collections.singletonList(SsaScopeType.SSA_ADMIN.getValue());

// Register client
RegisterResponse registerResponse = registerClient(redirectUris, Collections.singletonList(ResponseType.CODE),
Collections.singletonList(GrantType.CLIENT_CREDENTIALS), scopes, sectorIdentifierUri);
String clientId = registerResponse.getClientId();
String clientSecret = registerResponse.getClientSecret();

// Access token
TokenResponse tokenResponse = tokenClientCredentialsGrant(SsaScopeType.SSA_ADMIN.getValue(), clientId, clientSecret);
String accessToken = tokenResponse.getAccessToken();

String jti = "wrong-jti";

// Get Jwt of SSA
SsaGetJwtClient ssaGetJwtClient = new SsaGetJwtClient(ssaEndpoint);
SsaGetJwtResponse ssaGetJwtResponse = ssaGetJwtClient.execGetJwtSsa(accessToken, jti);
showClient(ssaGetJwtClient);
AssertBuilder.ssaGetJwt(ssaGetJwtResponse).status(422).check();
}

@Parameters({"redirectUris", "sectorIdentifierUri"})
@Test
public void getJwtSsaWithSsaPortalScopeResponseUnauthorized(final String redirectUris, final String sectorIdentifierUri) {
showTitle("getJwtSsaWithSsaPortalScopeResponseUnauthorized");
List<String> scopes = Collections.singletonList(SsaScopeType.SSA_ADMIN.getValue());

// Register client with scope admin
RegisterResponse registerResponse = registerClient(redirectUris, Collections.singletonList(ResponseType.CODE),
Collections.singletonList(GrantType.CLIENT_CREDENTIALS), scopes, sectorIdentifierUri);
String clientId = registerResponse.getClientId();
String clientSecret = registerResponse.getClientSecret();

// Access token
TokenResponse tokenResponse = tokenClientCredentialsGrant(SsaScopeType.SSA_ADMIN.getValue(), clientId, clientSecret);
String accessToken = tokenResponse.getAccessToken();

// Create ssa
SsaCreateResponse ssaCreateResponse = createSsaWithDefaultValues(accessToken, null, null, Boolean.TRUE);
String jti = ssaCreateResponse.getJti();

// Create a new client with scope portal
scopes = Collections.singletonList(SsaScopeType.SSA_PORTAL.getValue());
registerResponse = registerClient(redirectUris, Collections.singletonList(ResponseType.CODE),
Collections.singletonList(GrantType.CLIENT_CREDENTIALS), scopes, sectorIdentifierUri);
clientId = registerResponse.getClientId();
clientSecret = registerResponse.getClientSecret();

// Access token
tokenResponse = tokenClientCredentialsGrant(SsaScopeType.SSA_ADMIN.getValue(), clientId, clientSecret);
accessToken = tokenResponse.getAccessToken();

// Get JWT of SSA
SsaGetJwtClient ssaGetJwtClient = new SsaGetJwtClient(ssaEndpoint);
SsaGetJwtResponse ssaGetJwtResponse = ssaGetJwtClient.execGetJwtSsa(accessToken, jti);
showClient(ssaGetJwtClient);
AssertBuilder.ssaGetJwt(ssaGetJwtResponse).status(401).check();
}
}
6 changes: 6 additions & 0 deletions jans-auth-server/client/src/test/resources/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1195,4 +1195,10 @@
<class name="io.jans.as.client.ssa.SsaRevokeTest"/>
</classes>
</test>

<test name="SSA get JWT test (HTTP)" enabled="true">
<classes>
<class name="io.jans.as.client.ssa.SsaGetJwtTest"/>
</classes>
</test>
</suite>
Loading

0 comments on commit 7dcca94

Please sign in to comment.