Merge pull request #2635 from ssilvert/migrate-oauth-client-2
KEYCLOAK-2743: Port OAuthClient to new testsuite
This commit is contained in:
commit
44c3a56a21
41 changed files with 1306 additions and 99 deletions
|
@ -44,6 +44,11 @@ public class AssertEventsServletFilter implements Filter {
|
|||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
|
||||
if ("/clear-event-queue".equals(req.getRequestURI().substring(req.getContextPath().length()))) {
|
||||
EventsListenerProvider.getInstance().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ("/event-queue".equals(req.getRequestURI().substring(req.getContextPath().length()))) {
|
||||
BlockingQueue<Event> events = EventsListenerProvider.getInstance();
|
||||
HttpServletResponse resp = (HttpServletResponse) servletResponse;
|
||||
|
|
|
@ -69,6 +69,7 @@ public class EventsServer {
|
|||
FilterInfo filter = Servlets.filter("EventsFilter", AssertEventsServletFilter.class);
|
||||
di.addFilter(filter);
|
||||
di.addFilterUrlMapping("EventsFilter", "/event-queue", DispatcherType.REQUEST);
|
||||
di.addFilterUrlMapping("EventsFilter", "/clear-event-queue", DispatcherType.REQUEST);
|
||||
|
||||
DeploymentManager manager = container.addDeployment(di);
|
||||
manager.deploy();
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.rest;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.services.resource.RealmResourceProvider;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class TestApplicationResourceProvider implements RealmResourceProvider {
|
||||
|
||||
private KeycloakSession session;
|
||||
|
||||
public TestApplicationResourceProvider(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@Path("/{action}")
|
||||
public String get(@PathParam("action") String action) {
|
||||
//String requestUri = session.getContext().getUri().getRequestUri().toString();
|
||||
|
||||
String title = "APP_REQUEST";
|
||||
if (action.equals("auth")) {
|
||||
title = "AUTH_RESPONSE";
|
||||
} else if (action.equals("logout")) {
|
||||
title = "LOGOUT_REQUEST";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><head><title>" + title + "</title></head><body>");
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
|
||||
|
||||
sb.append("</body></html>");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResource() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.rest;
|
||||
|
||||
import org.keycloak.Config.Scope;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.resource.RealmResourceProvider;
|
||||
import org.keycloak.services.resource.RealmResourceProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class TestApplicationResourceProviderFactory implements RealmResourceProviderFactory {
|
||||
|
||||
@Override
|
||||
public RealmResourceProvider create(KeycloakSession session) {
|
||||
return new TestApplicationResourceProvider(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Scope config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "app";
|
||||
}
|
||||
|
||||
}
|
|
@ -15,4 +15,5 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
org.keycloak.testsuite.rest.TimeOffsetResourceProviderFactory
|
||||
org.keycloak.testsuite.rest.TimeOffsetResourceProviderFactory
|
||||
org.keycloak.testsuite.rest.TestApplicationResourceProviderFactory
|
|
@ -21,7 +21,7 @@ import org.jboss.arquillian.core.api.Instance;
|
|||
import org.jboss.arquillian.core.api.annotation.Inject;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.DeleteMeOAuthClient;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
|
@ -31,11 +31,11 @@ import java.lang.annotation.Annotation;
|
|||
public class OAuthClientProvider implements ResourceProvider {
|
||||
|
||||
@Inject
|
||||
Instance<OAuthClient> oauthClient;
|
||||
Instance<DeleteMeOAuthClient> oauthClient;
|
||||
|
||||
@Override
|
||||
public boolean canProvide(Class<?> type) {
|
||||
return OAuthClient.class.isAssignableFrom(type);
|
||||
return DeleteMeOAuthClient.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,11 +40,11 @@ import java.util.List;
|
|||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class OAuthClient {
|
||||
public class DeleteMeOAuthClient {
|
||||
|
||||
private String baseUrl;
|
||||
|
||||
public OAuthClient(String baseUrl) {
|
||||
public DeleteMeOAuthClient(String baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
|
@ -60,19 +60,23 @@ import org.keycloak.testsuite.admin.ApiUtil;
|
|||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
import org.keycloak.testsuite.auth.page.WelcomePage;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.DeleteMeOAuthClient;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.keycloak.testsuite.auth.page.AuthServer;
|
||||
import org.keycloak.testsuite.auth.page.AuthServerContextRoot;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
||||
|
||||
import org.keycloak.testsuite.auth.page.account.Account;
|
||||
import org.keycloak.testsuite.auth.page.login.OIDCLogin;
|
||||
import org.keycloak.testsuite.auth.page.login.UpdatePassword;
|
||||
import org.keycloak.testsuite.util.WaitUtils;
|
||||
|
||||
import static org.keycloak.testsuite.admin.Users.setPasswordFor;
|
||||
|
||||
import org.keycloak.testsuite.util.TestEventsLogger;
|
||||
|
||||
/**
|
||||
|
@ -93,7 +97,7 @@ public abstract class AbstractKeycloakTest {
|
|||
|
||||
protected Keycloak adminClient;
|
||||
|
||||
protected OAuthClient oauthClient;
|
||||
protected DeleteMeOAuthClient oauthClient;
|
||||
|
||||
protected List<RealmRepresentation> testRealmReps;
|
||||
|
||||
|
@ -128,7 +132,7 @@ public abstract class AbstractKeycloakTest {
|
|||
public void beforeAbstractKeycloakTest() {
|
||||
adminClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
||||
oauthClient = new OAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
|
||||
oauthClient = new DeleteMeOAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
|
||||
|
||||
|
||||
adminUser = createAdminUserRepresentation();
|
||||
|
@ -155,7 +159,7 @@ public abstract class AbstractKeycloakTest {
|
|||
}
|
||||
|
||||
// removeTestRealms(); // keeping test realms after test to be able to inspect failures, instead deleting existing realms before import
|
||||
// keycloak.close(); // keeping admin connection open
|
||||
// adminClient.close(); // keeping admin connection open
|
||||
}
|
||||
|
||||
private void updateMasterAdminPassword() {
|
||||
|
|
|
@ -57,7 +57,7 @@ public class AssertEvents {
|
|||
static final String DEFAULT_REALM = "test";
|
||||
static final String DEFAULT_USERNAME = "test-user@localhost";
|
||||
|
||||
String defaultRedirectUri = "http://localhost:8081/app/auth";
|
||||
String defaultRedirectUri = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
String defaultEventsQueueUri = "http://localhost:8092";
|
||||
|
||||
private RealmResource realmResource;
|
||||
|
@ -96,7 +96,23 @@ public class AssertEvents {
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
realmResource.clearEvents();
|
||||
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||
try {
|
||||
HttpPost post = new HttpPost(defaultEventsQueueUri + "/clear-event-queue");
|
||||
CloseableHttpResponse response = httpclient.execute(post);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new RuntimeException("Failed to clear events from " + post.getURI() + ": " + response.getStatusLine().toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
httpclient.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ExpectedEvent expectRequiredAction(EventType event) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite;
|
||||
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||
|
||||
/**
|
||||
* This class provides loading of the testRealm called "test". It also
|
||||
* provides an OAuthClient for the testRealm.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest {
|
||||
|
||||
protected OAuthClient oauth;
|
||||
|
||||
protected ClientRepresentation findTestApp(RealmRepresentation testRealm) {
|
||||
for (ClientRepresentation client : testRealm.getClients()) {
|
||||
if (client.getClientId().equals("test-app")) return client;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
|
||||
|
||||
oauth = new OAuthClient(driver, testRealm.getPublicKey());
|
||||
|
||||
testRealms.add(testRealm);
|
||||
|
||||
configureTestRealm(testRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows a subclass to change the configuration of the testRealm before
|
||||
* it is imported. This method will be called prior to any @Before methods
|
||||
* in the subclass.
|
||||
*
|
||||
* @param testRealm The realm read from /testrealm.json.
|
||||
*/
|
||||
public abstract void configureTestRealm(RealmRepresentation testRealm);
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.admin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.TestRealmKeycloakTest;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
/**
|
||||
* This class adapts the functionality from the old testsuite to make tests
|
||||
* easier to port.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public abstract class AbstractAdminTest extends TestRealmKeycloakTest {
|
||||
protected static final String REALM_NAME = "admin-client-test";
|
||||
|
||||
protected RealmResource realm;
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
findTestApp(testRealm).setDirectAccessGrantsEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
super.addTestRealms(testRealms);
|
||||
|
||||
RealmRepresentation adminRealmRep = new RealmRepresentation();
|
||||
adminRealmRep.setRealm(REALM_NAME);
|
||||
adminRealmRep.setEnabled(true);
|
||||
Map<String, String> config = new HashMap<>();
|
||||
config.put("from", "auto@keycloak.org");
|
||||
config.put("host", "localhost");
|
||||
config.put("port", "3025");
|
||||
adminRealmRep.setSmtpServer(config);
|
||||
testRealms.add(adminRealmRep);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setRealm() {
|
||||
realm = adminClient.realm(REALM_NAME);
|
||||
}
|
||||
|
||||
// old testsuite expects this realm to be removed at the end of the test
|
||||
// not sure if it really matters
|
||||
@After
|
||||
public void after() {
|
||||
for (RealmRepresentation r : adminClient.realms().findAll()) {
|
||||
if (r.getRealm().equals(REALM_NAME)) {
|
||||
removeRealm(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from Keycloak class in old testsuite.
|
||||
// So, code in old testsuite calling this looks like Keycloak.loadJson(.....)
|
||||
public static <T> T loadJson(InputStream is, Class<T> type) {
|
||||
try {
|
||||
return JsonSerialization.readValue(is, type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to parse json", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void assertNames(List<T> actual, String... expected) {
|
||||
Arrays.sort(expected);
|
||||
String[] actualNames = names(actual);
|
||||
assertArrayEquals("Expected: " + Arrays.toString(expected) + ", was: " + Arrays.toString(actualNames), expected, actualNames);
|
||||
}
|
||||
|
||||
public static <T> List<T> sort(List<T> list) {
|
||||
Collections.sort(list, new Comparator<Object>() {
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
return name(o1).compareTo(name(o2));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> String[] names(List<T> list) {
|
||||
String[] names = new String[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
names[i] = name(list.get(i));
|
||||
}
|
||||
Arrays.sort(names);
|
||||
return names;
|
||||
}
|
||||
|
||||
public static String name(Object o1) {
|
||||
if (o1 instanceof RealmRepresentation) {
|
||||
return ((RealmRepresentation) o1).getRealm();
|
||||
} else if (o1 instanceof ClientRepresentation) {
|
||||
return ((ClientRepresentation) o1).getClientId();
|
||||
} else if (o1 instanceof IdentityProviderRepresentation) {
|
||||
return ((IdentityProviderRepresentation) o1).getAlias();
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.admin;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.Response.StatusType;
|
||||
|
||||
import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD;
|
||||
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
|
||||
/**
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class ApiUtil {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ApiUtil.class);
|
||||
|
||||
public static String getCreatedId(Response response) {
|
||||
URI location = response.getLocation();
|
||||
if (!response.getStatusInfo().equals(Status.CREATED)) {
|
||||
StatusType statusInfo = response.getStatusInfo();
|
||||
throw new RuntimeException("Create method returned status " +
|
||||
statusInfo.getReasonPhrase() + " (Code: " + statusInfo.getStatusCode() + "); expected status: Created (201)");
|
||||
}
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
String path = location.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
public static ClientResource findClientResourceByClientId(RealmResource realm, String clientId) {
|
||||
for (ClientRepresentation c : realm.clients().findAll()) {
|
||||
if (c.getClientId().equals(clientId)) {
|
||||
return realm.clients().get(c.getId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClientResource findClientResourceByName(RealmResource realm, String name) {
|
||||
for (ClientRepresentation c : realm.clients().findAll()) {
|
||||
if (c.getName().equals(name)) {
|
||||
return realm.clients().get(c.getId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClientResource findClientByClientId(RealmResource realm, String clientId) {
|
||||
for (ClientRepresentation c : realm.clients().findAll()) {
|
||||
if (c.getClientId().equals(clientId)) {
|
||||
return realm.clients().get(c.getId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UserRepresentation findUserByUsername(RealmResource realm, String username) {
|
||||
UserRepresentation user = null;
|
||||
List<UserRepresentation> ur = realm.users().search(username, null, null);
|
||||
if (ur.size() == 1) {
|
||||
user = ur.get(0);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public static String createUserWithAdminClient(RealmResource realm, UserRepresentation user) {
|
||||
Response response = realm.users().create(user);
|
||||
String createdId = getCreatedId(response);
|
||||
response.close();
|
||||
return createdId;
|
||||
}
|
||||
|
||||
public static String createUserAndResetPasswordWithAdminClient(RealmResource realm, UserRepresentation user, String password) {
|
||||
String id = createUserWithAdminClient(realm, user);
|
||||
resetUserPassword(realm.users().get(id), password, false);
|
||||
return id;
|
||||
}
|
||||
|
||||
public static void resetUserPassword(UserResource userResource, String newPassword, boolean temporary) {
|
||||
CredentialRepresentation newCredential = new CredentialRepresentation();
|
||||
newCredential.setType(PASSWORD);
|
||||
newCredential.setValue(newPassword);
|
||||
newCredential.setTemporary(temporary);
|
||||
userResource.resetPassword(newCredential);
|
||||
}
|
||||
|
||||
public static void assignClientRoles(RealmResource realm, String userId, String clientName, String... roles) {
|
||||
String realmName = realm.toRepresentation().getRealm();
|
||||
String clientId = "";
|
||||
for (ClientRepresentation clientRepresentation : realm.clients().findAll()) {
|
||||
if (clientRepresentation.getClientId().equals(clientName)) {
|
||||
clientId = clientRepresentation.getId();
|
||||
}
|
||||
}
|
||||
|
||||
if (!clientId.isEmpty()) {
|
||||
ClientResource clientResource = realm.clients().get(clientId);
|
||||
|
||||
List<RoleRepresentation> roleRepresentations = new ArrayList<>();
|
||||
for (String roleName : roles) {
|
||||
RoleRepresentation role = clientResource.roles().get(roleName).toRepresentation();
|
||||
roleRepresentations.add(role);
|
||||
}
|
||||
|
||||
UserResource userResource = realm.users().get(userId);
|
||||
log.debug("assigning roles: " + Arrays.toString(roles) + " to user: \""
|
||||
+ userResource.toRepresentation().getUsername() + "\" of client: \""
|
||||
+ clientName + "\" in realm: \"" + realmName + "\"");
|
||||
userResource.roles().clientLevel(clientId).add(roleRepresentations);
|
||||
} else {
|
||||
log.warn("client with name " + clientName + "doesn't exist in realm " + realmName);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean groupContainsSubgroup(GroupRepresentation group, GroupRepresentation subgroup) {
|
||||
boolean contains = false;
|
||||
for (GroupRepresentation sg : group.getSubGroups()) {
|
||||
if (subgroup.getId().equals(sg.getId())) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,17 +18,12 @@
|
|||
package org.keycloak.testsuite.admin;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ProtocolMappersResource;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||
import org.keycloak.representations.idm.*;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -36,6 +31,7 @@ import javax.ws.rs.core.Response;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -47,16 +43,7 @@ import static org.junit.Assert.fail;
|
|||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ClientTest extends AbstractClientTest {
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
public class ClientTest extends AbstractAdminTest {
|
||||
|
||||
@Test
|
||||
public void getClients() {
|
||||
|
@ -122,7 +109,7 @@ public class ClientTest extends AbstractClientTest {
|
|||
OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(codeResponse.getCode(), "password");
|
||||
assertEquals(200, response2.getStatusCode());
|
||||
|
||||
ClientResource app = ApiUtil.findClientByClientId(keycloak.realm("test"), "test-app");
|
||||
ClientResource app = ApiUtil.findClientByClientId(adminClient.realm("test"), "test-app");
|
||||
|
||||
assertEquals(2, (long) app.getApplicationSessionCount().get("count"));
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.authentication;
|
||||
package org.keycloak.testsuite.endpoint.authentication;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.Response;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.testsuite.endpoint.client;
|
||||
|
||||
import java.util.List;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.event;
|
||||
package org.keycloak.testsuite.endpoint.event;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.junit.Before;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.event;
|
||||
package org.keycloak.testsuite.endpoint.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.event;
|
||||
package org.keycloak.testsuite.endpoint.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
|
@ -15,7 +15,7 @@
|
|||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.event;
|
||||
package org.keycloak.testsuite.endpoint.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.group;
|
||||
package org.keycloak.testsuite.endpoint.group;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
|
@ -45,6 +45,7 @@ public abstract class AbstractGroupTest extends AbstractKeycloakTest {
|
|||
@Before
|
||||
public void initAssertEvents() throws Exception {
|
||||
events = new AssertEvents(this);
|
||||
events.clear();
|
||||
}
|
||||
|
||||
AccessToken login(String login, String clientId, String clientSecret, String userId) throws Exception {
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.group;
|
||||
package org.keycloak.testsuite.endpoint.group;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.group;
|
||||
package org.keycloak.testsuite.endpoint.group;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -14,7 +14,7 @@
|
|||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.testsuite.admin.partialimport;
|
||||
package org.keycloak.testsuite.endpoint.partialimport;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
|
@ -41,7 +41,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
|
||||
/**
|
||||
* Test importing JSON files exported from previous keycloak versions
|
||||
* Test importing JSON files exported from previous adminClient versions
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
|
@ -18,49 +18,47 @@ package org.keycloak.testsuite.oauth;
|
|||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.testsuite.util.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.oidc.TokenMetadataRepresentation;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.testsuite.TestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
|
||||
//import org.adminClient.testsuite.pages.LoginPage;
|
||||
//import org.adminClient.testsuite.rule.KeycloakRule;
|
||||
//import org.adminClient.testsuite.rule.WebResource;
|
||||
//import org.adminClient.testsuite.rule.WebRule;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class TokenIntrospectionTest {
|
||||
public class TokenIntrospectionTest extends TestRealmKeycloakTest {
|
||||
|
||||
protected static Keycloak keycloak;
|
||||
|
||||
@ClassRule
|
||||
private AssertEvents events;
|
||||
|
||||
/* @ClassRule >>> now implemented in configureTestRealm()
|
||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
vvv "test" realm
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
vvv Done in TestRealmKeycloakTest vvv
|
||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||
|
||||
ClientModel confApp = KeycloakModelUtils.createClient(appRealm, "confidential-cli");
|
||||
confApp.setSecret("secret1");
|
||||
new ClientManager(manager).enableServiceAccount(confApp);
|
||||
|
@ -74,25 +72,39 @@ public class TokenIntrospectionTest {
|
|||
user.grantRole(role);
|
||||
}
|
||||
|
||||
keycloak = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
adminClient = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
}
|
||||
|
||||
});
|
||||
}); */
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
ClientRepresentation confApp = KeycloakModelUtils.createClient(testRealm, "confidential-cli");
|
||||
confApp.setSecret("secret1");
|
||||
confApp.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
ClientRepresentation pubApp = KeycloakModelUtils.createClient(testRealm, "public-cli");
|
||||
pubApp.setPublicClient(Boolean.TRUE);
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setUsername("no-permissions");
|
||||
CredentialRepresentation credential = new CredentialRepresentation();
|
||||
credential.setType("password");
|
||||
credential.setValue("password");
|
||||
List<CredentialRepresentation> creds = new ArrayList<>();
|
||||
creds.add(credential);
|
||||
user.setCredentials(creds);
|
||||
user.setEnabled(Boolean.TRUE);
|
||||
List<String> realmRoles = new ArrayList<>();
|
||||
realmRoles.add("user");
|
||||
user.setRealmRoles(realmRoles);
|
||||
testRealm.getUsers().add(user);
|
||||
}
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
||||
@Before
|
||||
public void setUpAssertEvents() throws Exception {
|
||||
events = new AssertEvents(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfidentialClientCredentialsBasicAuthentication() throws Exception {
|
||||
|
@ -146,7 +158,7 @@ public class TokenIntrospectionTest {
|
|||
public void testIntrospectRefreshToken() throws Exception {
|
||||
oauth.doLogin("test-user@localhost", "password");
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
Event loginEvent = events.expectLogin().assertEvent();
|
||||
EventRepresentation loginEvent = events.expectLogin().assertEvent();
|
||||
String sessionId = loginEvent.getSessionId();
|
||||
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
|
||||
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
|
||||
|
@ -215,7 +227,7 @@ public class TokenIntrospectionTest {
|
|||
public void testIntrospectAccessToken() throws Exception {
|
||||
oauth.doLogin("test-user@localhost", "password");
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
Event loginEvent = events.expectLogin().assertEvent();
|
||||
EventRepresentation loginEvent = events.expectLogin().assertEvent();
|
||||
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
|
||||
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
|
||||
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
|
||||
|
@ -252,12 +264,12 @@ public class TokenIntrospectionTest {
|
|||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Event loginEvent = events.expectLogin().assertEvent();
|
||||
EventRepresentation loginEvent = events.expectLogin().assertEvent();
|
||||
|
||||
UserRepresentation userRep = new UserRepresentation();
|
||||
try {
|
||||
userRep.setEnabled(false);
|
||||
keycloak.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
|
||||
adminClient.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
|
||||
|
||||
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
|
||||
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
|
||||
|
@ -270,7 +282,7 @@ public class TokenIntrospectionTest {
|
|||
events.clear();
|
||||
} finally {
|
||||
userRep.setEnabled(true);
|
||||
keycloak.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
|
||||
adminClient.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,7 +293,7 @@ public class TokenIntrospectionTest {
|
|||
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
try {
|
||||
Time.setOffset(keycloak.realm(oauth.getRealm()).toRepresentation().getAccessTokenLifespan() + 1);
|
||||
Time.setOffset(adminClient.realm(oauth.getRealm()).toRepresentation().getAccessTokenLifespan() + 1);
|
||||
|
||||
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
|
||||
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.util;
|
||||
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import static org.keycloak.models.utils.KeycloakModelUtils.getDefaultClientAuthenticatorType;
|
||||
|
||||
/**
|
||||
* This is a client-side version of KeycloakModelUtils that uses the adminClient to
|
||||
* manipulate the model.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class KeycloakModelUtils {
|
||||
|
||||
public static ClientRepresentation createClient(RealmRepresentation realm, String name) {
|
||||
ClientRepresentation app = new ClientRepresentation();
|
||||
app.setName(name);
|
||||
app.setClientId(name);
|
||||
realm.getClients().add(app);
|
||||
app.setClientAuthenticatorType(getDefaultClientAuthenticatorType());
|
||||
generateSecret(app);
|
||||
app.setFullScopeAllowed(true);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
public static CredentialRepresentation generateSecret(ClientRepresentation client) {
|
||||
UserCredentialModel secret = UserCredentialModel.generateSecret();
|
||||
client.setSecret(secret.getValue());
|
||||
return ModelToRepresentation.toRepresentation(secret);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,645 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.util;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.junit.Assert;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.RSATokenVerifier;
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.constants.AdapterConstants;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.util.BasicAuthHelper;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
*/
|
||||
public class OAuthClient {
|
||||
public static final String SERVER_ROOT = AuthServerTestEnricher.getAuthServerContextRoot();
|
||||
public static final String AUTH_SERVER_ROOT = SERVER_ROOT + "/auth";
|
||||
public static final String APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app";
|
||||
|
||||
private WebDriver driver;
|
||||
|
||||
private String baseUrl = AUTH_SERVER_ROOT;
|
||||
|
||||
private String realm = "test";
|
||||
|
||||
private String clientId = "test-app";
|
||||
|
||||
private String redirectUri = APP_ROOT + "/auth";
|
||||
|
||||
private String state = "mystate";
|
||||
|
||||
private String scope;
|
||||
|
||||
private String uiLocales = null;
|
||||
|
||||
private PublicKey realmPublicKey;
|
||||
|
||||
private String clientSessionState;
|
||||
|
||||
private String clientSessionHost;
|
||||
|
||||
public OAuthClient(WebDriver driver, String publicKey) {
|
||||
this.driver = driver;
|
||||
|
||||
try {
|
||||
realmPublicKey = PemUtils.decodePublicKey(publicKey);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve realm public key", e);
|
||||
}
|
||||
}
|
||||
|
||||
public AuthorizationCodeResponse doLogin(String username, String password) {
|
||||
openLoginForm();
|
||||
String src = driver.getPageSource();
|
||||
driver.findElement(By.id("username")).sendKeys(username);
|
||||
driver.findElement(By.id("password")).sendKeys(password);
|
||||
driver.findElement(By.name("login")).click();
|
||||
|
||||
return new AuthorizationCodeResponse(this);
|
||||
}
|
||||
|
||||
public void doLoginGrant(String username, String password) {
|
||||
openLoginForm();
|
||||
|
||||
driver.findElement(By.id("username")).sendKeys(username);
|
||||
driver.findElement(By.id("password")).sendKeys(password);
|
||||
driver.findElement(By.name("login")).click();
|
||||
}
|
||||
|
||||
public AccessTokenResponse doAccessTokenRequest(String code, String password) {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getAccessTokenUrl());
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE));
|
||||
|
||||
if (code != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CODE, code));
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri));
|
||||
}
|
||||
if (clientId != null && password != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, password);
|
||||
post.setHeader("Authorization", authorization);
|
||||
} else if (clientId != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
|
||||
}
|
||||
|
||||
if (clientSessionState != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
|
||||
}
|
||||
|
||||
if (clientSessionHost != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity = null;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
try {
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve access token", e);
|
||||
}
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public String introspectAccessTokenWithClientCredential(String clientId, String clientSecret, String tokenToIntrospect) {
|
||||
return introspectTokenWithClientCredential(clientId, clientSecret, "access_token", tokenToIntrospect);
|
||||
}
|
||||
|
||||
public String introspectRefreshTokenWithClientCredential(String clientId, String clientSecret, String tokenToIntrospect) {
|
||||
return introspectTokenWithClientCredential(clientId, clientSecret, "refresh_token", tokenToIntrospect);
|
||||
}
|
||||
|
||||
public String introspectTokenWithClientCredential(String clientId, String clientSecret, String tokenType, String tokenToIntrospect) {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getTokenIntrospectionUrl());
|
||||
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
|
||||
post.setHeader("Authorization", authorization);
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<>();
|
||||
|
||||
parameters.add(new BasicNameValuePair("token", tokenToIntrospect));
|
||||
parameters.add(new BasicNameValuePair("token_type_hint", tokenType));
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
post.setEntity(formEntity);
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
client.execute(post).getEntity().writeTo(out);
|
||||
|
||||
return new String(out.toByteArray());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve access token", e);
|
||||
}
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessTokenResponse doGrantAccessTokenRequest(String clientSecret, String username, String password) throws Exception {
|
||||
return doGrantAccessTokenRequest(realm, username, password, null, clientId, clientSecret);
|
||||
}
|
||||
|
||||
public AccessTokenResponse doGrantAccessTokenRequest(String clientSecret, String username, String password, String otp) throws Exception {
|
||||
return doGrantAccessTokenRequest(realm, username, password, otp, clientId, clientSecret);
|
||||
}
|
||||
|
||||
public AccessTokenResponse doGrantAccessTokenRequest(String realm, String username, String password, String totp,
|
||||
String clientId, String clientSecret) throws Exception {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getResourceOwnerPasswordCredentialGrantUrl(realm));
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD));
|
||||
parameters.add(new BasicNameValuePair("username", username));
|
||||
parameters.add(new BasicNameValuePair("password", password));
|
||||
if (totp != null) {
|
||||
parameters.add(new BasicNameValuePair("totp", totp));
|
||||
|
||||
}
|
||||
if (clientSecret != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
|
||||
post.setHeader("Authorization", authorization);
|
||||
} else {
|
||||
parameters.add(new BasicNameValuePair("client_id", clientId));
|
||||
|
||||
}
|
||||
|
||||
if (clientSessionState != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
|
||||
}
|
||||
if (clientSessionHost != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
|
||||
}
|
||||
if (scope != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.SCOPE, scope));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessTokenResponse doClientCredentialsGrantAccessTokenRequest(String clientSecret) throws Exception {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getServiceAccountUrl());
|
||||
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
|
||||
post.setHeader("Authorization", authorization);
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.CLIENT_CREDENTIALS));
|
||||
|
||||
if (scope != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.SCOPE, scope));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public HttpResponse doLogout(String refreshToken, String clientSecret) throws IOException {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getLogoutUrl(null, null));
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
if (refreshToken != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
|
||||
}
|
||||
if (clientId != null && clientSecret != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
|
||||
post.setHeader("Authorization", authorization);
|
||||
} else if (clientId != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
return client.execute(post);
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessTokenResponse doRefreshTokenRequest(String refreshToken, String password) {
|
||||
CloseableHttpClient client = new DefaultHttpClient();
|
||||
try {
|
||||
HttpPost post = new HttpPost(getRefreshTokenUrl());
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.REFRESH_TOKEN));
|
||||
|
||||
if (refreshToken != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
|
||||
}
|
||||
if (clientId != null && password != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, password);
|
||||
post.setHeader("Authorization", authorization);
|
||||
} else if (clientId != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
|
||||
}
|
||||
|
||||
if (clientSessionState != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
|
||||
}
|
||||
if (clientSessionHost != null) {
|
||||
parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
try {
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve access token", e);
|
||||
}
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeClient(CloseableHttpClient client) {
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessToken verifyToken(String token) {
|
||||
try {
|
||||
return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/realms/" + realm);
|
||||
} catch (VerificationException e) {
|
||||
throw new RuntimeException("Failed to verify token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public RefreshToken verifyRefreshToken(String refreshToken) {
|
||||
try {
|
||||
JWSInput jws = new JWSInput(refreshToken);
|
||||
if (!RSAProvider.verify(jws, realmPublicKey)) {
|
||||
throw new RuntimeException("Invalid refresh token");
|
||||
}
|
||||
return jws.readJsonContent(RefreshToken.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Invalid refresh token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getCurrentRequest() {
|
||||
return driver.getCurrentUrl().substring(0, driver.getCurrentUrl().indexOf('?'));
|
||||
}
|
||||
|
||||
public URI getCurrentUri() {
|
||||
try {
|
||||
return new URI(driver.getCurrentUrl());
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getCurrentQuery() {
|
||||
Map<String, String> m = new HashMap<String, String>();
|
||||
List<NameValuePair> pairs = URLEncodedUtils.parse(getCurrentUri(), "UTF-8");
|
||||
for (NameValuePair p : pairs) {
|
||||
m.put(p.getName(), p.getValue());
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public void openLoginForm() {
|
||||
driver.navigate().to(getLoginFormUrl());
|
||||
}
|
||||
|
||||
public void openLogout() {
|
||||
UriBuilder b = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(baseUrl));
|
||||
if (redirectUri != null) {
|
||||
b.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri);
|
||||
}
|
||||
driver.navigate().to(b.build(realm).toString());
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public String getLoginFormUrl() {
|
||||
UriBuilder b = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(SERVER_ROOT + "/auth"));
|
||||
b.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE);
|
||||
if (clientId != null) {
|
||||
b.queryParam(OAuth2Constants.CLIENT_ID, clientId);
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
b.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri);
|
||||
}
|
||||
if (state != null) {
|
||||
b.queryParam(OAuth2Constants.STATE, state);
|
||||
}
|
||||
if(uiLocales != null){
|
||||
b.queryParam(OAuth2Constants.UI_LOCALES_PARAM, uiLocales);
|
||||
}
|
||||
if (scope != null) {
|
||||
b.queryParam(OAuth2Constants.SCOPE, scope);
|
||||
}
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getAccessTokenUrl() {
|
||||
UriBuilder b = OIDCLoginProtocolService.tokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getTokenIntrospectionUrl() {
|
||||
UriBuilder b = OIDCLoginProtocolService.tokenIntrospectionUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getLogoutUrl(String redirectUri, String sessionState) {
|
||||
UriBuilder b = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(baseUrl));
|
||||
if (redirectUri != null) {
|
||||
b.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri);
|
||||
}
|
||||
if (sessionState != null) {
|
||||
b.queryParam("session_state", sessionState);
|
||||
}
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getResourceOwnerPasswordCredentialGrantUrl() {
|
||||
UriBuilder b = OIDCLoginProtocolService.tokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getResourceOwnerPasswordCredentialGrantUrl(String realm) {
|
||||
UriBuilder b = OIDCLoginProtocolService.tokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getServiceAccountUrl() {
|
||||
return getResourceOwnerPasswordCredentialGrantUrl();
|
||||
}
|
||||
|
||||
public String getRefreshTokenUrl() {
|
||||
UriBuilder b = OIDCLoginProtocolService.tokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public OAuthClient realm(String realm) {
|
||||
this.realm = realm;
|
||||
return this;
|
||||
}
|
||||
public OAuthClient realmPublicKey(PublicKey key) {
|
||||
this.realmPublicKey = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient clientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient redirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient state(String state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient scope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient uiLocales(String uiLocales){
|
||||
this.uiLocales = uiLocales;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient clientSessionState(String client_session_state) {
|
||||
this.clientSessionState = client_session_state;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient clientSessionHost(String client_session_host) {
|
||||
this.clientSessionHost = client_session_host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public static class AuthorizationCodeResponse {
|
||||
|
||||
private boolean isRedirected;
|
||||
private String code;
|
||||
private String state;
|
||||
private String error;
|
||||
|
||||
public AuthorizationCodeResponse(OAuthClient client) {
|
||||
isRedirected = client.getCurrentRequest().equals(client.getRedirectUri());
|
||||
code = client.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
state = client.getCurrentQuery().get(OAuth2Constants.STATE);
|
||||
error = client.getCurrentQuery().get(OAuth2Constants.ERROR);
|
||||
}
|
||||
|
||||
public boolean isRedirected() {
|
||||
return isRedirected;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AccessTokenResponse {
|
||||
private int statusCode;
|
||||
|
||||
private String accessToken;
|
||||
private String tokenType;
|
||||
private int expiresIn;
|
||||
private int refreshExpiresIn;
|
||||
private String refreshToken;
|
||||
|
||||
private String error;
|
||||
private String errorDescription;
|
||||
|
||||
public AccessTokenResponse(HttpResponse response) throws Exception {
|
||||
statusCode = response.getStatusLine().getStatusCode();
|
||||
if (!"application/json".equals(response.getHeaders("Content-Type")[0].getValue())) {
|
||||
Assert.fail("Invalid content type");
|
||||
}
|
||||
|
||||
String s = IOUtils.toString(response.getEntity().getContent());
|
||||
Map responseJson = JsonSerialization.readValue(s, Map.class);
|
||||
|
||||
if (statusCode == 200) {
|
||||
accessToken = (String)responseJson.get("access_token");
|
||||
tokenType = (String)responseJson.get("token_type");
|
||||
expiresIn = (Integer)responseJson.get("expires_in");
|
||||
refreshExpiresIn = (Integer)responseJson.get("refresh_expires_in");
|
||||
|
||||
if (responseJson.containsKey(OAuth2Constants.REFRESH_TOKEN)) {
|
||||
refreshToken = (String)responseJson.get(OAuth2Constants.REFRESH_TOKEN);
|
||||
}
|
||||
} else {
|
||||
error = (String)responseJson.get(OAuth2Constants.ERROR);
|
||||
errorDescription = responseJson.containsKey(OAuth2Constants.ERROR_DESCRIPTION) ? (String)responseJson.get(OAuth2Constants.ERROR_DESCRIPTION) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public String getErrorDescription() {
|
||||
return errorDescription;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public int getRefreshExpiresIn() {
|
||||
return refreshExpiresIn;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -101,11 +101,11 @@
|
|||
{
|
||||
"clientId": "test-app",
|
||||
"enabled": true,
|
||||
"baseUrl": "http://localhost:8081/app",
|
||||
"baseUrl": "http://localhost:8180/auth/realms/master/app",
|
||||
"redirectUris": [
|
||||
"http://localhost:8081/app/*"
|
||||
"http://localhost:8180/auth/realms/master/app/*"
|
||||
],
|
||||
"adminUrl": "http://localhost:8081/app/logout",
|
||||
"adminUrl": "http://localhost:8180/auth/realms/master/app/logout",
|
||||
"secret": "password"
|
||||
},
|
||||
{
|
||||
|
@ -114,7 +114,7 @@
|
|||
"consentRequired": true,
|
||||
|
||||
"redirectUris": [
|
||||
"http://localhost:8081/app/*"
|
||||
"http://localhost:8180/app/*"
|
||||
],
|
||||
"secret": "password"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue