allow specifying format of "permission" parameter in the UMA grant token
endpoint (#15947)
This commit is contained in:
parent
e9accaf387
commit
bd37875a66
7 changed files with 256 additions and 12 deletions
|
@ -134,6 +134,14 @@ public class HttpMethodAuthenticator<R> {
|
||||||
if (metadata.getResponseMode() != null) {
|
if (metadata.getResponseMode() != null) {
|
||||||
method.param("response_mode", metadata.getResponseMode());
|
method.param("response_mode", metadata.getResponseMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (metadata.getPermissionResourceFormat() != null) {
|
||||||
|
method.param("permission_resource_format", metadata.getPermissionResourceFormat().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata.getPermissionResourceMatchingUri() != null) {
|
||||||
|
method.param("permission_resource_matching_uri", metadata.getPermissionResourceMatchingUri().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return method;
|
return method;
|
||||||
|
|
|
@ -187,6 +187,8 @@ public class AuthorizationRequest {
|
||||||
private Boolean includeResourceName;
|
private Boolean includeResourceName;
|
||||||
private Integer limit;
|
private Integer limit;
|
||||||
private String responseMode;
|
private String responseMode;
|
||||||
|
private String permissionResourceFormat;
|
||||||
|
private Boolean permissionResourceMatchingUri;
|
||||||
|
|
||||||
public Boolean getIncludeResourceName() {
|
public Boolean getIncludeResourceName() {
|
||||||
if (includeResourceName == null) {
|
if (includeResourceName == null) {
|
||||||
|
@ -214,5 +216,21 @@ public class AuthorizationRequest {
|
||||||
public String getResponseMode() {
|
public String getResponseMode() {
|
||||||
return responseMode;
|
return responseMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPermissionResourceFormat() {
|
||||||
|
return permissionResourceFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionResourceFormat(String permissionResourceFormat) {
|
||||||
|
this.permissionResourceFormat = permissionResourceFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getPermissionResourceMatchingUri() {
|
||||||
|
return permissionResourceMatchingUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionResourceMatchingUri(Boolean permissionResourceMatchingUri) {
|
||||||
|
this.permissionResourceMatchingUri = permissionResourceMatchingUri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,14 @@ This parameter is *optional*. A string representing a set of one or more resourc
|
||||||
in order to request permission for multiple resource and scopes. This parameter is an extension to `urn:ietf:params:oauth:grant-type:uma-ticket` grant type in order to allow clients to send authorization requests without a
|
in order to request permission for multiple resource and scopes. This parameter is an extension to `urn:ietf:params:oauth:grant-type:uma-ticket` grant type in order to allow clients to send authorization requests without a
|
||||||
permission ticket. The format of the string must be: `RESOURCE_ID#SCOPE_ID`. For instance: `Resource A#Scope A`, `Resource A#Scope A, Scope B, Scope C`, `Resource A`, `#Scope A`.
|
permission ticket. The format of the string must be: `RESOURCE_ID#SCOPE_ID`. For instance: `Resource A#Scope A`, `Resource A#Scope A, Scope B, Scope C`, `Resource A`, `#Scope A`.
|
||||||
+
|
+
|
||||||
|
* **permission_resource_format**
|
||||||
|
+
|
||||||
|
This parameter is *optional*. A string representing a format indicating the resource in the `permission` parameter. Possible values are `id` and `uri`. `id` indicates the format is `RESOURCE_ID`. `uri` indicates the format is `URI`. If not specified, the default is `id`.
|
||||||
|
+
|
||||||
|
* **permission_resource_matching_uri**
|
||||||
|
+
|
||||||
|
This parameter is *optional*. A boolean value that indicates whether to use path matching when representing resources in URI format in the `permission` parameter. If not specified, the default is false.
|
||||||
|
+
|
||||||
* **audience**
|
* **audience**
|
||||||
+
|
+
|
||||||
This parameter is *optional*. The client identifier of the resource server to which the client is seeking access. This parameter is mandatory
|
This parameter is *optional*. The client identifier of the resource server to which the client is seeking access. This parameter is mandatory
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.authorization.authorization;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -59,12 +61,14 @@ import org.keycloak.authorization.util.Tokens;
|
||||||
import org.keycloak.common.ClientConnection;
|
import org.keycloak.common.ClientConnection;
|
||||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||||
import org.keycloak.common.util.Base64Url;
|
import org.keycloak.common.util.Base64Url;
|
||||||
|
import org.keycloak.common.util.PathMatcher;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionContext;
|
import org.keycloak.models.ClientSessionContext;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
@ -802,5 +806,129 @@ public class AuthorizationTokenService {
|
||||||
ClientConnection getClientConnection() {
|
ClientConnection getClientConnection() {
|
||||||
return clientConnection;
|
return clientConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPermissions(List<String> permissionList, String permissionResourceFormat, boolean matchingUri) {
|
||||||
|
if (permissionResourceFormat == null) {
|
||||||
|
permissionResourceFormat = "id";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (permissionResourceFormat) {
|
||||||
|
case "id":
|
||||||
|
addPermissionsById(permissionList);
|
||||||
|
break;
|
||||||
|
case "uri":
|
||||||
|
addPermissionsByUri(permissionList, matchingUri);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPermissionsById(List<String> permissionList) {
|
||||||
|
for (String permission : permissionList) {
|
||||||
|
String[] parts = permission.split("#");
|
||||||
|
String rsid = parts[0];
|
||||||
|
|
||||||
|
if (parts.length == 1) {
|
||||||
|
addPermission(rsid);
|
||||||
|
} else {
|
||||||
|
String[] scopes = parts[1].split(",");
|
||||||
|
addPermission(rsid, scopes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPermissionsByUri(List<String> permissionList, boolean matchingUri) {
|
||||||
|
StoreFactory storeFactory = authorization.getStoreFactory();
|
||||||
|
|
||||||
|
for (String permission : permissionList) {
|
||||||
|
String[] parts = permission.split("#");
|
||||||
|
String uri = parts[0];
|
||||||
|
|
||||||
|
if (parts.length == 1) {
|
||||||
|
// only resource uri is specified
|
||||||
|
if (uri.isEmpty()) {
|
||||||
|
CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(getCors(),
|
||||||
|
OAuthErrorException.INVALID_REQUEST, "You must provide the uri", Status.BAD_REQUEST);
|
||||||
|
fireErrorEvent(getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
|
||||||
|
throw invalidResourceException;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Resource> resources = getResourceListByUri(uri, storeFactory, matchingUri);
|
||||||
|
|
||||||
|
if (resources == null || resources.isEmpty()) {
|
||||||
|
CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(getCors(),
|
||||||
|
"invalid_resource", "Resource with uri [" + uri + "] does not exist.", Status.BAD_REQUEST);
|
||||||
|
fireErrorEvent(getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
|
||||||
|
throw invalidResourceException;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources.stream().forEach(resource -> addPermission(resource.getId()));
|
||||||
|
} else {
|
||||||
|
// resource uri and scopes are specified, or only scopes are specified
|
||||||
|
String[] scopes = parts[1].split(",");
|
||||||
|
|
||||||
|
if (uri.isEmpty()) {
|
||||||
|
// only scopes are specified
|
||||||
|
addPermission("", scopes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Resource> resources = getResourceListByUri(uri, storeFactory, matchingUri);
|
||||||
|
|
||||||
|
if (resources == null || resources.isEmpty()) {
|
||||||
|
CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(getCors(),
|
||||||
|
"invalid_resource", "Resource with uri [" + uri + "] does not exist.", Status.BAD_REQUEST);
|
||||||
|
fireErrorEvent(getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
|
||||||
|
throw invalidResourceException;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources.stream().forEach(resource -> addPermission(resource.getId(), scopes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Resource> getResourceListByUri(String uri, StoreFactory storeFactory, boolean matchingUri) {
|
||||||
|
Map<Resource.FilterOption, String[]> search = new EnumMap<>(Resource.FilterOption.class);
|
||||||
|
search.put(Resource.FilterOption.URI, new String[] { uri });
|
||||||
|
ResourceServer resourceServer = storeFactory.getResourceServerStore()
|
||||||
|
.findByClient(getRealm().getClientByClientId(getAudience()));
|
||||||
|
List<Resource> resources = storeFactory.getResourceStore().find(getRealm(), resourceServer, search, -1,
|
||||||
|
Constants.DEFAULT_MAX_RESULTS);
|
||||||
|
|
||||||
|
if (!matchingUri || !resources.isEmpty()) {
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
search = new EnumMap<>(Resource.FilterOption.class);
|
||||||
|
search.put(Resource.FilterOption.URI_NOT_NULL, new String[] { "true" });
|
||||||
|
search.put(Resource.FilterOption.OWNER, new String[] { resourceServer.getClientId() });
|
||||||
|
|
||||||
|
List<Resource> serverResources = storeFactory.getResourceStore().find(getRealm(), resourceServer, search, -1, -1);
|
||||||
|
|
||||||
|
PathMatcher<Map.Entry<String, Resource>> pathMatcher = new PathMatcher<Map.Entry<String, Resource>>() {
|
||||||
|
@Override
|
||||||
|
protected String getPath(Map.Entry<String, Resource> entry) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<Map.Entry<String, Resource>> getPaths() {
|
||||||
|
Map<String, Resource> result = new HashMap<>();
|
||||||
|
serverResources.forEach(resource -> resource.getUris().forEach(uri -> {
|
||||||
|
result.put(uri, resource);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return result.entrySet();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Map.Entry<String, Resource> matches = pathMatcher.matches(uri);
|
||||||
|
|
||||||
|
if (matches != null) {
|
||||||
|
return Collections.singletonList(matches.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -960,17 +960,9 @@ public class TokenEndpoint {
|
||||||
|
|
||||||
if (permissions != null) {
|
if (permissions != null) {
|
||||||
event.detail(Details.PERMISSION, String.join("|", permissions));
|
event.detail(Details.PERMISSION, String.join("|", permissions));
|
||||||
for (String permission : permissions) {
|
String permissionResourceFormat = formParams.getFirst("permission_resource_format");
|
||||||
String[] parts = permission.split("#");
|
boolean permissionResourceMatchingUri = Boolean.parseBoolean(formParams.getFirst("permission_resource_matching_uri"));
|
||||||
String resource = parts[0];
|
authorizationRequest.addPermissions(permissions, permissionResourceFormat, permissionResourceMatchingUri);
|
||||||
|
|
||||||
if (parts.length == 1) {
|
|
||||||
authorizationRequest.addPermission(resource);
|
|
||||||
} else {
|
|
||||||
String[] scopes = parts[1].split(",");
|
|
||||||
authorizationRequest.addPermission(parts[0], scopes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.testsuite.authz;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -35,6 +36,7 @@ import org.keycloak.authorization.client.AuthzClient;
|
||||||
import org.keycloak.authorization.client.resource.ProtectionResource;
|
import org.keycloak.authorization.client.resource.ProtectionResource;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
||||||
|
import org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata;
|
||||||
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
|
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
|
||||||
import org.keycloak.representations.idm.authorization.Permission;
|
import org.keycloak.representations.idm.authorization.Permission;
|
||||||
import org.keycloak.representations.idm.authorization.PermissionRequest;
|
import org.keycloak.representations.idm.authorization.PermissionRequest;
|
||||||
|
@ -165,6 +167,31 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
|
||||||
return authorization.authorize(authorizationRequest);
|
return authorization.authorize(authorizationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected AuthorizationResponse authorizeDecision(String accessToken, Boolean matchingUri, PermissionRequest... permissions) {
|
||||||
|
AuthorizationRequest authorizationRequest = new AuthorizationRequest();
|
||||||
|
|
||||||
|
org.keycloak.authorization.client.resource.AuthorizationResource authorization;
|
||||||
|
|
||||||
|
if (accessToken != null) {
|
||||||
|
authorization = getAuthzClient().authorization(accessToken);
|
||||||
|
} else {
|
||||||
|
authorization = getAuthzClient().authorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PermissionRequest permission : permissions)
|
||||||
|
authorizationRequest.addPermission(permission.getResourceId(), new ArrayList<String>(permission.getScopes()));
|
||||||
|
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.setResponseMode("decision");
|
||||||
|
metadata.setPermissionResourceFormat("uri");
|
||||||
|
if (matchingUri != null)
|
||||||
|
metadata.setPermissionResourceMatchingUri(matchingUri);
|
||||||
|
|
||||||
|
authorizationRequest.setMetadata(metadata);
|
||||||
|
|
||||||
|
return authorization.authorize(authorizationRequest);
|
||||||
|
}
|
||||||
|
|
||||||
protected RealmResource getRealm() {
|
protected RealmResource getRealm() {
|
||||||
return adminClient.realm("authz-test");
|
return adminClient.realm("authz-test");
|
||||||
}
|
}
|
||||||
|
@ -209,6 +236,11 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ResourceRepresentation addResource(String resourceName, String owner, boolean ownerManagedAccess, String... scopeNames) throws Exception {
|
protected ResourceRepresentation addResource(String resourceName, String owner, boolean ownerManagedAccess, String... scopeNames) throws Exception {
|
||||||
|
return addResource(resourceName, owner, null, ownerManagedAccess, scopeNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResourceRepresentation addResource(String resourceName, String owner, Set<String> uris,
|
||||||
|
boolean ownerManagedAccess, String... scopeNames) throws Exception {
|
||||||
ClientResource client = getClient(getRealm());
|
ClientResource client = getClient(getRealm());
|
||||||
AuthorizationResource authorization = client.authorization();
|
AuthorizationResource authorization = client.authorization();
|
||||||
ResourceRepresentation resource = new ResourceRepresentation(resourceName);
|
ResourceRepresentation resource = new ResourceRepresentation(resourceName);
|
||||||
|
@ -219,6 +251,9 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
|
||||||
|
|
||||||
resource.setOwnerManagedAccess(ownerManagedAccess);
|
resource.setOwnerManagedAccess(ownerManagedAccess);
|
||||||
resource.addScope(scopeNames);
|
resource.addScope(scopeNames);
|
||||||
|
if (uris != null) {
|
||||||
|
resource.setUris(uris);
|
||||||
|
}
|
||||||
|
|
||||||
Response response = authorization.resources().create(resource);
|
Response response = authorization.resources().create(resource);
|
||||||
ResourceRepresentation temp = response.readEntity(ResourceRepresentation.class);
|
ResourceRepresentation temp = response.readEntity(ResourceRepresentation.class);
|
||||||
|
|
|
@ -30,6 +30,7 @@ import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -95,7 +96,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
|
||||||
authorization.policies().js().create(policy).close();
|
authorization.policies().js().create(policy).close();
|
||||||
|
|
||||||
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
|
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
|
||||||
resourceA = addResource("Resource A", "ScopeA", "ScopeB", "ScopeC");
|
resourceA = addResource("Resource A", null, Collections.singleton("/resource"), false, "ScopeA", "ScopeB", "ScopeC");
|
||||||
|
|
||||||
permission.setName(resourceA.getName() + " Permission");
|
permission.setName(resourceA.getName() + " Permission");
|
||||||
permission.addResource(resourceA.getName());
|
permission.addResource(resourceA.getName());
|
||||||
|
@ -371,6 +372,60 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
|
||||||
assertTrue(permissions.isEmpty());
|
assertTrue(permissions.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testObtainDecisionUsingAccessToken() throws Exception {
|
||||||
|
AccessTokenResponse accessTokenResponse = getAuthzClient().obtainAccessToken("marta", "password");
|
||||||
|
|
||||||
|
// use "rsid" as "uri"
|
||||||
|
// uri and scopes exist
|
||||||
|
AuthorizationResponse response = authorizeDecision(accessTokenResponse.getToken(), null,
|
||||||
|
new PermissionRequest("/resource", "ScopeA", "ScopeB"));
|
||||||
|
assertTrue((Boolean) response.getOtherClaims().getOrDefault("result", "false"));
|
||||||
|
|
||||||
|
// uri and scopes are empty
|
||||||
|
try {
|
||||||
|
response = authorizeDecision(accessTokenResponse.getToken(), null, new PermissionRequest(null));
|
||||||
|
fail();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// uri is empty but scopes exist
|
||||||
|
response = authorizeDecision(accessTokenResponse.getToken(), null, new PermissionRequest(null, "ScopeA", "ScopeB"));
|
||||||
|
assertTrue((Boolean) response.getOtherClaims().getOrDefault("result", "false"));
|
||||||
|
|
||||||
|
// test wild card
|
||||||
|
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
|
||||||
|
ResourceRepresentation resourceB = addResource("Resource B", null, Collections.singleton("/rs/*"), false, "ScopeD",
|
||||||
|
"ScopeE");
|
||||||
|
|
||||||
|
permission.setName(resourceB.getName() + " Permission");
|
||||||
|
permission.addResource(resourceB.getName());
|
||||||
|
permission.addPolicy("Default Policy");
|
||||||
|
|
||||||
|
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
|
||||||
|
|
||||||
|
// matchingUri is null, then result error
|
||||||
|
try {
|
||||||
|
response = authorizeDecision(accessTokenResponse.getToken(), null,
|
||||||
|
new PermissionRequest("/rs/data", "ScopeD", "ScopeE"));
|
||||||
|
fail();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchingUri is true, then result true
|
||||||
|
response = authorizeDecision(accessTokenResponse.getToken(), true,
|
||||||
|
new PermissionRequest("/rs/data", "ScopeD", "ScopeE"));
|
||||||
|
assertTrue((Boolean) response.getOtherClaims().getOrDefault("result", "false"));
|
||||||
|
|
||||||
|
// matchingUri is false, then result error
|
||||||
|
try {
|
||||||
|
response = authorizeDecision(accessTokenResponse.getToken(), false,
|
||||||
|
new PermissionRequest("/rs/data", "ScopeD", "ScopeE"));
|
||||||
|
fail();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCORSHeadersInFailedRptRequest() throws Exception {
|
public void testCORSHeadersInFailedRptRequest() throws Exception {
|
||||||
AccessTokenResponse accessTokenResponse = getAuthzClient().obtainAccessToken("marta", "password");
|
AccessTokenResponse accessTokenResponse = getAuthzClient().obtainAccessToken("marta", "password");
|
||||||
|
|
Loading…
Reference in a new issue