[KEYCLOAK-3372] - Adding tests for servlet authorization
This commit is contained in:
parent
3c8ed8e3d8
commit
607b305c2f
19 changed files with 949 additions and 2 deletions
|
@ -7,5 +7,5 @@
|
||||||
String contextPath = request.getContextPath();
|
String contextPath = request.getContextPath();
|
||||||
String redirectUri = scheme + "://" + host + ":" + port + contextPath;
|
String redirectUri = scheme + "://" + host + ":" + port + contextPath;
|
||||||
%>
|
%>
|
||||||
<h2>Click <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8080/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||||
.queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">here</a> to logout.</h2>
|
.queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">Sign Out</a></h2>
|
|
@ -20,5 +20,6 @@
|
||||||
<module>js-database</module>
|
<module>js-database</module>
|
||||||
<module>photoz</module>
|
<module>photoz</module>
|
||||||
<module>hello-world-authz-service</module>
|
<module>hello-world-authz-service</module>
|
||||||
|
<module>servlet-authz</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,54 @@
|
||||||
|
# About the Example Application
|
||||||
|
|
||||||
|
This is a simple Servlet-based application that will introduce you to some of the main concepts around Keycloak Authorization Services.
|
||||||
|
|
||||||
|
For this application, users can be regular users, premium users or administrators, where:
|
||||||
|
|
||||||
|
* Regular users have very limited access.
|
||||||
|
* Premium users have access to the *premium area*
|
||||||
|
* Administrators have access to the *administration area*
|
||||||
|
|
||||||
|
In Keycloak, all the paths being protected are resources on the server.
|
||||||
|
|
||||||
|
This application will also show you how to create a dynamic menu with the permissions granted to an user.
|
||||||
|
|
||||||
|
## Create the Example Realm and a Resource Server
|
||||||
|
|
||||||
|
Considering that your Keycloak Server is up and running, log in to the Keycloak Administration Console.
|
||||||
|
|
||||||
|
Now, create a new realm based on the following configuration file:
|
||||||
|
|
||||||
|
examples/authz/servlet-authz/servlet-authz-realm.json
|
||||||
|
|
||||||
|
That will import a pre-configured realm with everything you need to run this example. For more details about how to import a realm
|
||||||
|
into Keycloak, check the Keycloak's reference documentation.
|
||||||
|
|
||||||
|
After importing that file, you'll have a new realm called ``servlet-authz``.
|
||||||
|
|
||||||
|
Now, let's import another configuration using the Administration Console in order to configure the client application ``servlet-authz-app`` as a resource server with all resources, scopes, permissions and policies.
|
||||||
|
|
||||||
|
Click on ``Clients`` on the left side menu. Click on the ``servlet-authz-app`` on the client listing page. This will
|
||||||
|
open the ``Client Details`` page. Once there, click on the `Authorization` tab.
|
||||||
|
|
||||||
|
Click on the ``Select file`` button, which means you want to import a resource server configuration. Now select the file that is located at:
|
||||||
|
|
||||||
|
examples/authz/servlet-authz/servlet-authz-app-config.json
|
||||||
|
|
||||||
|
Now click ``Upload`` and the resource server will be updated accordingly.
|
||||||
|
|
||||||
|
## Deploy and Run the Example Applications
|
||||||
|
|
||||||
|
To deploy the example application, follow these steps:
|
||||||
|
|
||||||
|
cd examples/authz/servlet-authz
|
||||||
|
mvn clean package wildfly:deploy
|
||||||
|
|
||||||
|
Now, try to access the client application using the following URL:
|
||||||
|
|
||||||
|
http://localhost:8080/servlet-authz-app
|
||||||
|
|
||||||
|
If everything is correct, you will be redirect to Keycloak login page. You can login to the application with the following credentials:
|
||||||
|
|
||||||
|
* username: jdoe / password: jdoe
|
||||||
|
* username: alice / password: alice
|
||||||
|
* username: admin / password: admin
|
53
testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml
Executable file
53
testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
|
<artifactId>integration-arquillian-test-apps</artifactId>
|
||||||
|
<version>2.1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>servlet-authz-app</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<name>Keycloak Authz: Servlet Authorization Test</name>
|
||||||
|
<description>Servlet Authorization Test</description>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-authz-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jboss.as.plugins</groupId>
|
||||||
|
<artifactId>jboss-as-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>false</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.wildfly.plugins</groupId>
|
||||||
|
<artifactId>wildfly-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>false</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,147 @@
|
||||||
|
{
|
||||||
|
"allowRemoteResourceManagement": true,
|
||||||
|
"policyEnforcementMode": "ENFORCING",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"name": "Admin Resource",
|
||||||
|
"uri": "/protected/admin/*",
|
||||||
|
"type": "http://servlet-authz/protected/admin",
|
||||||
|
"scopes": [
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:protected:admin:access"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Protected Resource",
|
||||||
|
"uri": "/*",
|
||||||
|
"type": "http://servlet-authz/protected/resource",
|
||||||
|
"scopes": [
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:protected:resource:access"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Premium Resource",
|
||||||
|
"uri": "/protected/premium/*",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"scopes": [
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:protected:premium:access"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Main Page",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"scopes": [
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:page:main:actionForAdmin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:page:main:actionForUser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "urn:servlet-authz:page:main:actionForPremiumUser"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"name": "Any Admin Policy",
|
||||||
|
"description": "Defines that adminsitrators can do something",
|
||||||
|
"type": "role",
|
||||||
|
"config": {
|
||||||
|
"roles": "[{\"id\":\"admin\"}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Any User Policy",
|
||||||
|
"description": "Defines that any user can do something",
|
||||||
|
"type": "role",
|
||||||
|
"config": {
|
||||||
|
"roles": "[{\"id\":\"user\"}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Only Premium User Policy",
|
||||||
|
"description": "Defines that only premium users can do something",
|
||||||
|
"type": "role",
|
||||||
|
"logic": "POSITIVE",
|
||||||
|
"config": {
|
||||||
|
"roles": "[{\"id\":\"user_premium\"}]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "All Users Policy",
|
||||||
|
"description": "Defines that all users can do something",
|
||||||
|
"type": "aggregate",
|
||||||
|
"decisionStrategy": "AFFIRMATIVE",
|
||||||
|
"config": {
|
||||||
|
"applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Premium Resource Permission",
|
||||||
|
"description": "A policy that defines access to premium resources",
|
||||||
|
"type": "resource",
|
||||||
|
"decisionStrategy": "UNANIMOUS",
|
||||||
|
"config": {
|
||||||
|
"resources": "[\"Premium Resource\"]",
|
||||||
|
"applyPolicies": "[\"Only Premium User Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Administrative Resource Permission",
|
||||||
|
"description": "A policy that defines access to administrative resources",
|
||||||
|
"type": "resource",
|
||||||
|
"decisionStrategy": "UNANIMOUS",
|
||||||
|
"config": {
|
||||||
|
"resources": "[\"Admin Resource\"]",
|
||||||
|
"applyPolicies": "[\"Any Admin Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Protected Resource Permission",
|
||||||
|
"description": "A policy that defines access to any protected resource",
|
||||||
|
"type": "resource",
|
||||||
|
"decisionStrategy": "AFFIRMATIVE",
|
||||||
|
"config": {
|
||||||
|
"resources": "[\"Protected Resource\"]",
|
||||||
|
"applyPolicies": "[\"All Users Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Action 1 on Main Page Resource Permission",
|
||||||
|
"description": "A policy that defines access to action 1 on the main page",
|
||||||
|
"type": "scope",
|
||||||
|
"decisionStrategy": "AFFIRMATIVE",
|
||||||
|
"config": {
|
||||||
|
"scopes": "[\"urn:servlet-authz:page:main:actionForAdmin\"]",
|
||||||
|
"applyPolicies": "[\"Any Admin Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Action 2 on Main Page Resource Permission",
|
||||||
|
"description": "A policy that defines access to action 2 on the main page",
|
||||||
|
"type": "scope",
|
||||||
|
"decisionStrategy": "AFFIRMATIVE",
|
||||||
|
"config": {
|
||||||
|
"scopes": "[\"urn:servlet-authz:page:main:actionForUser\"]",
|
||||||
|
"applyPolicies": "[\"Any User Policy\"]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Action 3 on Main Page Resource Permission",
|
||||||
|
"description": "A policy that defines access to action 3 on the main page",
|
||||||
|
"type": "scope",
|
||||||
|
"decisionStrategy": "AFFIRMATIVE",
|
||||||
|
"config": {
|
||||||
|
"scopes": "[\"urn:servlet-authz:page:main:actionForPremiumUser\"]",
|
||||||
|
"applyPolicies": "[\"Only Premium User Policy\"]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
"realm": "servlet-authz",
|
||||||
|
"enabled": true,
|
||||||
|
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||||
|
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
|
"requiredCredentials": [
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"username": "alice",
|
||||||
|
"enabled": true,
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"type": "password",
|
||||||
|
"value": "alice"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"realmRoles": [
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "jdoe",
|
||||||
|
"enabled": true,
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"type": "password",
|
||||||
|
"value": "jdoe"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"realmRoles": [
|
||||||
|
"user",
|
||||||
|
"user_premium"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "admin",
|
||||||
|
"enabled": true,
|
||||||
|
"credentials": [
|
||||||
|
{
|
||||||
|
"type": "password",
|
||||||
|
"value": "admin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"realmRoles": [
|
||||||
|
"user",
|
||||||
|
"admin"
|
||||||
|
],
|
||||||
|
"clientRoles": {
|
||||||
|
"realm-management": [
|
||||||
|
"realm-admin"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "service-account-servlet-authz-app",
|
||||||
|
"enabled": true,
|
||||||
|
"serviceAccountClientId": "servlet-authz-app",
|
||||||
|
"clientRoles": {
|
||||||
|
"servlet-authz-app" : ["uma_protection"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"roles": {
|
||||||
|
"realm": [
|
||||||
|
{
|
||||||
|
"name": "user",
|
||||||
|
"description": "User privileges"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "admin",
|
||||||
|
"description": "Administrator privileges"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_premium",
|
||||||
|
"description": "User Premium privileges"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"clientId": "servlet-authz-app",
|
||||||
|
"enabled": true,
|
||||||
|
"baseUrl": "/servlet-authz-app",
|
||||||
|
"adminUrl": "/servlet-authz-app",
|
||||||
|
"bearerOnly": false,
|
||||||
|
"authorizationServicesEnabled": true,
|
||||||
|
"redirectUris": [
|
||||||
|
"/servlet-authz-app/*"
|
||||||
|
],
|
||||||
|
"secret": "secret"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<dependencies>
|
||||||
|
<module name="org.keycloak.keycloak-authz-client" services="import"/>
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"realm": "servlet-authz",
|
||||||
|
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
|
"auth-server-url" : "http://localhost:8180/auth",
|
||||||
|
"ssl-required" : "external",
|
||||||
|
"resource" : "servlet-authz-app",
|
||||||
|
"public-client" : false,
|
||||||
|
"credentials": {
|
||||||
|
"secret": "secret"
|
||||||
|
},
|
||||||
|
"policy-enforcer": {
|
||||||
|
"on-deny-redirect-to" : "/servlet-authz-app/accessDenied.jsp"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||||
|
version="3.0">
|
||||||
|
|
||||||
|
<module-name>servlet-authz-app</module-name>
|
||||||
|
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>All Resources</web-resource-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>All Resources</web-resource-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>KEYCLOAK</auth-method>
|
||||||
|
<realm-name>servlet-authz</realm-name>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</security-role>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</security-role>
|
||||||
|
|
||||||
|
<error-page>
|
||||||
|
<error-code>403</error-code>
|
||||||
|
<location>/accessDenied.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h2 style="color: red">You can not access this resource.</h2>
|
||||||
|
<%@include file="logout-include.jsp"%>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<%@page import="org.keycloak.AuthorizationContext" %>
|
||||||
|
<%@ page import="org.keycloak.KeycloakSecurityContext" %>
|
||||||
|
<%@ page import="org.keycloak.representations.idm.authorization.Permission" %>
|
||||||
|
|
||||||
|
<%
|
||||||
|
KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||||
|
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
|
||||||
|
%>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<%@include file="logout-include.jsp"%>
|
||||||
|
<h2>This is a public resource. Try to access one of these <i>protected</i> resources:</h2>
|
||||||
|
|
||||||
|
<p><a href="protected/dynamicMenu.jsp">Dynamic Menu</a></p>
|
||||||
|
<p><a href="protected/premium/onlyPremium.jsp">User Premium</a></p>
|
||||||
|
<p><a href="protected/admin/onlyAdmin.jsp">Administration</a></p>
|
||||||
|
|
||||||
|
<h3>Your permissions are:</h3>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<%
|
||||||
|
for (Permission permission : authzContext.getPermissions()) {
|
||||||
|
%>
|
||||||
|
<li>
|
||||||
|
<p>Resource: <%= permission.getResourceSetName() %></p>
|
||||||
|
<p>ID: <%= permission.getResourceSetId() %></p>
|
||||||
|
<p>Scopes: <%= permission.getScopes() %></p>
|
||||||
|
</li>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<%@ page import="org.keycloak.common.util.KeycloakUriBuilder" %>
|
||||||
|
<%@ page import="org.keycloak.constants.ServiceUrlConstants" %>
|
||||||
|
<%
|
||||||
|
String scheme = request.getScheme();
|
||||||
|
String host = request.getServerName();
|
||||||
|
int port = request.getServerPort();
|
||||||
|
String contextPath = request.getContextPath();
|
||||||
|
String redirectUri = scheme + "://" + host + ":" + port + contextPath;
|
||||||
|
%>
|
||||||
|
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8180/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||||
|
.queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">Sign Out</a></h2>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h2>Only Administrators can access this page.</h2>
|
||||||
|
<%@include file="../../logout-include.jsp"%>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,48 @@
|
||||||
|
<%@page import="org.keycloak.AuthorizationContext" %>
|
||||||
|
<%@ page import="org.keycloak.KeycloakSecurityContext" %>
|
||||||
|
|
||||||
|
<%
|
||||||
|
KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||||
|
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
|
||||||
|
%>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h2>Any authenticated user can access this page.</h2>
|
||||||
|
<%@include file="../logout-include.jsp"%>
|
||||||
|
|
||||||
|
<p>Here is a dynamic menu built from the permissions returned by the server:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<%
|
||||||
|
if (authzContext.hasResourcePermission("Protected Resource")) {
|
||||||
|
%>
|
||||||
|
<li>
|
||||||
|
Do user thing
|
||||||
|
</li>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%
|
||||||
|
if (authzContext.hasResourcePermission("Premium Resource")) {
|
||||||
|
%>
|
||||||
|
<li>
|
||||||
|
Do user premium thing
|
||||||
|
</li>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%
|
||||||
|
if (authzContext.hasPermission("Admin Resource", "urn:servlet-authz:protected:admin:access")) {
|
||||||
|
%>
|
||||||
|
<li>
|
||||||
|
Do administration thing
|
||||||
|
</li>
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h2>Only for premium users.</h2>
|
||||||
|
<%@include file="../../logout-include.jsp"%>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -43,5 +43,13 @@
|
||||||
<exclude name="**/subsystem-config.xml"/>
|
<exclude name="**/subsystem-config.xml"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
|
<copy todir="target/test-apps/servlet-authz-app" overwrite="true">
|
||||||
|
<fileset dir="../servlet-authz">
|
||||||
|
<exclude name="**/target/**"/>
|
||||||
|
<exclude name="**/*.iml"/>
|
||||||
|
<exclude name="**/*.unconfigured"/>
|
||||||
|
<exclude name="**/subsystem-config.xml"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,352 @@
|
||||||
|
/*
|
||||||
|
* 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.adapter.example.authorization;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployer;
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
|
import org.keycloak.admin.client.resource.ClientsResource;
|
||||||
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
|
import org.keycloak.admin.client.resource.RoleResource;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.admin.client.resource.UsersResource;
|
||||||
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
|
||||||
|
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.keycloak.testsuite.util.IOUtil.loadJson;
|
||||||
|
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
||||||
|
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractServletAuthzAdapterTest extends AbstractExampleAdapterTest {
|
||||||
|
|
||||||
|
private static final String REALM_NAME = "servlet-authz";
|
||||||
|
private static final String RESOURCE_SERVER_ID = "servlet-authz-app";
|
||||||
|
|
||||||
|
@ArquillianResource
|
||||||
|
private Deployer deployer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
testRealms.add(
|
||||||
|
loadRealm(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/servlet-authz-realm.json")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deployment(name = RESOURCE_SERVER_ID, managed = false)
|
||||||
|
public static WebArchive deployment() throws IOException {
|
||||||
|
return exampleDeployment(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeAbstractKeycloakTest() throws Exception {
|
||||||
|
super.beforeAbstractKeycloakTest();
|
||||||
|
importResourceServerSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserPermissions() throws Exception {
|
||||||
|
try {
|
||||||
|
this.deployer.deploy(RESOURCE_SERVER_ID);
|
||||||
|
|
||||||
|
login("alice", "alice");
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
|
||||||
|
assertTrue(hasLink("User Premium"));
|
||||||
|
assertTrue(hasLink("Administration"));
|
||||||
|
assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
|
||||||
|
assertFalse(hasText("urn:servlet-authz:page:main:actionForAdmin"));
|
||||||
|
assertFalse(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
|
||||||
|
|
||||||
|
navigateToDynamicMenuPage();
|
||||||
|
|
||||||
|
assertTrue(hasText("Do user thing"));
|
||||||
|
assertFalse(hasText("Do user premium thing"));
|
||||||
|
assertFalse(hasText("Do administration thing"));
|
||||||
|
|
||||||
|
|
||||||
|
navigateToUserPremiumPage();
|
||||||
|
|
||||||
|
assertTrue(wasDenied());
|
||||||
|
|
||||||
|
navigateToAdminPage();
|
||||||
|
|
||||||
|
assertTrue(wasDenied());
|
||||||
|
} finally {
|
||||||
|
this.deployer.undeploy(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserPremiumPermissions() throws Exception {
|
||||||
|
try {
|
||||||
|
this.deployer.deploy(RESOURCE_SERVER_ID);
|
||||||
|
|
||||||
|
login("jdoe", "jdoe");
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
assertTrue(hasLink("User Premium"));
|
||||||
|
assertTrue(hasLink("Administration"));
|
||||||
|
assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
|
||||||
|
assertTrue(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
|
||||||
|
assertFalse(hasText("urn:servlet-authz:page:main:actionForAdmin"));
|
||||||
|
|
||||||
|
navigateToDynamicMenuPage();
|
||||||
|
|
||||||
|
assertTrue(hasText("Do user thing"));
|
||||||
|
assertTrue(hasText("Do user premium thing"));
|
||||||
|
assertFalse(hasText("Do administration thing"));
|
||||||
|
} finally {
|
||||||
|
this.deployer.undeploy(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdminPermissions() throws Exception {
|
||||||
|
try {
|
||||||
|
this.deployer.deploy(RESOURCE_SERVER_ID);
|
||||||
|
|
||||||
|
login("admin", "admin");
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
|
||||||
|
assertTrue(hasLink("User Premium"));
|
||||||
|
assertTrue(hasLink("Administration"));
|
||||||
|
assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
|
||||||
|
assertTrue(hasText("urn:servlet-authz:page:main:actionForAdmin"));
|
||||||
|
assertFalse(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
|
||||||
|
|
||||||
|
navigateToDynamicMenuPage();
|
||||||
|
|
||||||
|
assertTrue(hasText("Do user thing"));
|
||||||
|
assertTrue(hasText("Do administration thing"));
|
||||||
|
assertFalse(hasText("Do user premium thing"));
|
||||||
|
} finally {
|
||||||
|
this.deployer.undeploy(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGrantPremiumAccess() throws Exception {
|
||||||
|
try {
|
||||||
|
this.deployer.deploy(RESOURCE_SERVER_ID);
|
||||||
|
|
||||||
|
login("alice", "alice");
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
|
||||||
|
navigateToUserPremiumPage();
|
||||||
|
|
||||||
|
assertTrue(wasDenied());
|
||||||
|
|
||||||
|
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
|
||||||
|
if ("Premium Resource Permission".equals(policy.getName())) {
|
||||||
|
policy.getConfig().put("applyPolicies", "[\"Any User Policy\"]");
|
||||||
|
getAuthorizationResource().policies().policy(policy.getId()).update(policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login("alice", "alice");
|
||||||
|
|
||||||
|
navigateToUserPremiumPage();
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
|
||||||
|
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
|
||||||
|
if ("Premium Resource Permission".equals(policy.getName())) {
|
||||||
|
policy.getConfig().put("applyPolicies", "[\"Only Premium User Policy\"]");
|
||||||
|
getAuthorizationResource().policies().policy(policy.getId()).update(policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login("alice", "alice");
|
||||||
|
navigateToUserPremiumPage();
|
||||||
|
|
||||||
|
assertTrue(wasDenied());
|
||||||
|
|
||||||
|
PolicyRepresentation onlyAlicePolicy = new PolicyRepresentation();
|
||||||
|
|
||||||
|
onlyAlicePolicy.setName("Temporary Premium Access Policy");
|
||||||
|
onlyAlicePolicy.setType("user");
|
||||||
|
HashMap<String, String> config = new HashMap<>();
|
||||||
|
UsersResource usersResource = realmsResouce().realm(REALM_NAME).users();
|
||||||
|
List<UserRepresentation> users = usersResource.search("alice", null, null, null, null, null);
|
||||||
|
|
||||||
|
assertFalse(users.isEmpty());
|
||||||
|
|
||||||
|
config.put("users", JsonSerialization.writeValueAsString(Arrays.asList(users.get(0).getId())));
|
||||||
|
|
||||||
|
onlyAlicePolicy.setConfig(config);
|
||||||
|
getAuthorizationResource().policies().create(onlyAlicePolicy);
|
||||||
|
|
||||||
|
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
|
||||||
|
if ("Premium Resource Permission".equals(policy.getName())) {
|
||||||
|
policy.getConfig().put("applyPolicies", "[\"Temporary Premium Access Policy\"]");
|
||||||
|
getAuthorizationResource().policies().policy(policy.getId()).update(policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logOut();
|
||||||
|
login("alice", "alice");
|
||||||
|
navigateToUserPremiumPage();
|
||||||
|
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
} finally {
|
||||||
|
this.deployer.undeploy(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGrantAdministrativePermissions() throws Exception {
|
||||||
|
try {
|
||||||
|
this.deployer.deploy(RESOURCE_SERVER_ID);
|
||||||
|
|
||||||
|
login("jdoe", "jdoe");
|
||||||
|
|
||||||
|
navigateToAdminPage();
|
||||||
|
assertTrue(wasDenied());
|
||||||
|
|
||||||
|
RealmResource realmResource = realmsResouce().realm(REALM_NAME);
|
||||||
|
UsersResource usersResource = realmResource.users();
|
||||||
|
List<UserRepresentation> users = usersResource.search("jdoe", null, null, null, null, null);
|
||||||
|
|
||||||
|
assertFalse(users.isEmpty());
|
||||||
|
|
||||||
|
UserResource userResource = usersResource.get(users.get(0).getId());
|
||||||
|
|
||||||
|
RoleRepresentation adminRole = realmResource.roles().get("admin").toRepresentation();
|
||||||
|
userResource.roles().realmLevel().add(Arrays.asList(adminRole));
|
||||||
|
|
||||||
|
login("jdoe", "jdoe");
|
||||||
|
|
||||||
|
navigateToAdminPage();
|
||||||
|
assertFalse(wasDenied());
|
||||||
|
} finally {
|
||||||
|
this.deployer.undeploy(RESOURCE_SERVER_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasLink(String text) {
|
||||||
|
return getLink(text) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasText(String text) {
|
||||||
|
return this.driver.getPageSource().contains(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement getLink(String text) {
|
||||||
|
return this.driver.findElement(By.xpath("//a[text() = '" + text + "']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void importResourceServerSettings() throws FileNotFoundException {
|
||||||
|
getAuthorizationResource().importSettings(loadJson(new FileInputStream(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/servlet-authz-app-authz-service.json")), ResourceServerRepresentation.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthorizationResource getAuthorizationResource() throws FileNotFoundException {
|
||||||
|
return getClientResource(RESOURCE_SERVER_ID).authorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientResource getClientResource(String clientId) {
|
||||||
|
ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
|
||||||
|
ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
|
||||||
|
return clients.get(resourceServer.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOut() {
|
||||||
|
navigateTo();
|
||||||
|
By by = By.xpath("//a[text() = 'Sign Out']");
|
||||||
|
WaitUtils.waitUntilElement(by);
|
||||||
|
this.driver.findElement(by).click();
|
||||||
|
pause(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void login(String username, String password) throws InterruptedException {
|
||||||
|
navigateTo();
|
||||||
|
Thread.sleep(2000);
|
||||||
|
if (this.driver.getCurrentUrl().startsWith(getResourceServerUrl().toString())) {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
logOut();
|
||||||
|
navigateTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(2000);
|
||||||
|
|
||||||
|
this.loginPage.form().login(username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateTo() {
|
||||||
|
this.driver.navigate().to(getResourceServerUrl());
|
||||||
|
WaitUtils.waitUntilElement(By.xpath("//a[text() = 'Dynamic Menu']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean wasDenied() {
|
||||||
|
return this.driver.getPageSource().contains("You can not access this resource.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private URL getResourceServerUrl() {
|
||||||
|
try {
|
||||||
|
return new URL(this.appServerContextRootPage + "/" + RESOURCE_SERVER_ID);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new RuntimeException("Could not obtain resource server url.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToDynamicMenuPage() {
|
||||||
|
navigateTo();
|
||||||
|
getLink("Dynamic Menu").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToUserPremiumPage() {
|
||||||
|
navigateTo();
|
||||||
|
getLink("User Premium").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToAdminPage() {
|
||||||
|
navigateTo();
|
||||||
|
getLink("Administration").click();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.adapter.example;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.RunAsClient;
|
||||||
|
import org.keycloak.testsuite.adapter.example.authorization.AbstractDefaultAuthzConfigAdapterTest;
|
||||||
|
import org.keycloak.testsuite.adapter.example.authorization.AbstractServletAuthzAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tkyjovsk
|
||||||
|
*/
|
||||||
|
@RunAsClient
|
||||||
|
@AppServerContainer("app-server-wildfly")
|
||||||
|
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
|
||||||
|
public class WildflyServletAuthzAdapterTest extends AbstractServletAuthzAdapterTest {
|
||||||
|
|
||||||
|
}
|
|
@ -287,6 +287,12 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</artifactItem>
|
</artifactItem>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
|
<artifactId>servlet-authz-app</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</artifactItem>
|
||||||
</artifactItems>
|
</artifactItems>
|
||||||
<outputDirectory>${examples.home}</outputDirectory>
|
<outputDirectory>${examples.home}</outputDirectory>
|
||||||
<overWriteIfNewer>true</overWriteIfNewer>
|
<overWriteIfNewer>true</overWriteIfNewer>
|
||||||
|
|
Loading…
Reference in a new issue