diff --git a/examples/demo-template/pom.xml b/examples/demo-template/pom.xml
index 7c33c28736..d6f3c12398 100755
--- a/examples/demo-template/pom.xml
+++ b/examples/demo-template/pom.xml
@@ -34,6 +34,7 @@
admin-access-app
angular-product-app
database-service
+ rest-resources
third-party
third-party-cdi
diff --git a/examples/demo-template/rest-resources/pom.xml b/examples/demo-template/rest-resources/pom.xml
new file mode 100755
index 0000000000..d27b9c0221
--- /dev/null
+++ b/examples/demo-template/rest-resources/pom.xml
@@ -0,0 +1,90 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 1.1.0.Final-SNAPSHOT
+ ../../../pom.xml
+
+ 4.0.0
+ org.keycloak.example.demo
+ rest-resources
+ war
+ Rest Resources
+
+
+
+
+ jboss
+ jboss repo
+ http://repository.jboss.org/nexus/content/groups/public/
+
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jaxrs
+ provided
+
+
+ org.jboss.spec.javax.servlet
+ jboss-servlet-api_3.0_spec
+ provided
+
+
+ org.keycloak
+ keycloak-core
+ ${project.version}
+ provided
+
+
+ org.keycloak
+ keycloak-adapter-core
+ ${project.version}
+ provided
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${keycloak.apache.httpcomponents.version}
+ provided
+
+
+
+
+ rest-resources
+
+
+ org.jboss.as.plugins
+ jboss-as-maven-plugin
+
+ false
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ ${maven.compiler.target}
+
+
+
+
+
diff --git a/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/PublicResources.java b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/PublicResources.java
new file mode 100755
index 0000000000..056f1d5d68
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/PublicResources.java
@@ -0,0 +1,36 @@
+package org.keycloak.example;
+
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.HttpRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+@Path("public")
+public class PublicResources {
+
+ @Context
+ HttpServletRequest request;
+
+ @POST
+ @Consumes("text/plain")
+ @Produces("text/plain")
+ @NoCache
+ public String get(String text) {
+ StringBuilder result = new StringBuilder();
+ Principal userPrincipal = request.getUserPrincipal();
+ if(userPrincipal != null){
+ result.append("Hello ").append(userPrincipal.getName()).append("\r\n");
+ }
+ result.append("You said: ").append(text);
+
+ return result.toString();
+ }
+}
diff --git a/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/ResourceApplication.java b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/ResourceApplication.java
new file mode 100755
index 0000000000..ab0040cefe
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/ResourceApplication.java
@@ -0,0 +1,9 @@
+package org.keycloak.example;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/")
+public class ResourceApplication extends Application
+{
+}
diff --git a/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/SecretResources.java b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/SecretResources.java
new file mode 100755
index 0000000000..ee5efa9d32
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/java/org/keycloak/example/SecretResources.java
@@ -0,0 +1,33 @@
+package org.keycloak.example;
+
+import org.jboss.resteasy.annotations.cache.NoCache;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import java.security.Principal;
+
+@Path("secret")
+public class SecretResources {
+
+ @Context
+ HttpServletRequest request;
+
+ @POST
+ @Consumes("text/plain")
+ @Produces("text/plain")
+ @NoCache
+ public String get(String text) {
+ StringBuilder result = new StringBuilder();
+ Principal userPrincipal = request.getUserPrincipal();
+ if(userPrincipal != null){
+ result.append("Hello ").append(userPrincipal.getName()).append("\r\n");
+ }
+ result.append("You said: ").append(text);
+
+ return result.toString();
+ }
+}
diff --git a/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
new file mode 100755
index 0000000000..9c1bac9b36
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/keycloak.json
new file mode 100755
index 0000000000..caed050a3f
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/keycloak.json
@@ -0,0 +1,7 @@
+{
+ "realm" : "demo",
+ "resource" : "rest-resources",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "/auth",
+ "ssl-required" : "external"
+}
diff --git a/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000000..1c619b0ee5
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+
+
+
+ rest-resources
+
+
+
+ Public
+ /public/*
+
+
+
+
+ Secure
+ /secure/*
+
+
+ user
+
+
+
+
+
+
+ KEYCLOAK
+ demo
+
+
+
+ user
+
+
diff --git a/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml.unconfigured b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml.unconfigured
new file mode 100755
index 0000000000..cce3b0b261
--- /dev/null
+++ b/examples/demo-template/rest-resources/src/main/webapp/WEB-INF/web.xml.unconfigured
@@ -0,0 +1,47 @@
+
+
+
+ rest-resources
+
+
+
+ Public
+ /public/*
+
+
+
+
+ Secure
+ /secure/*
+
+
+ user
+ admin
+
+
+
+
+
+
+ BASIC
+ demo
+
+
+
+ admin
+
+
+ user
+
+
diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json
index da92138a4e..a16e58ef34 100755
--- a/examples/demo-template/testrealm.json
+++ b/examples/demo-template/testrealm.json
@@ -148,6 +148,16 @@
"adminUrl": "/database",
"baseUrl": "/database",
"bearerOnly": true
+ },
+ {
+ "name": "rest-resources",
+ "enabled": true,
+ "publicClient": true,
+ "adminUrl": "/rest",
+ "baseUrl": "/rest",
+ "redirectUris": [
+ "/rest-resources/*"
+ ]
}
],
"oauthClients": [
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
index bd853da5f6..05a2773a99 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
@@ -76,6 +76,11 @@ public abstract class RequestAuthenticator {
}
}
+ if(!isAuthenticationRequired()){
+ log.debug("NOT_ATTEMPTED: authentication is not required");
+ return AuthOutcome.NOT_ATTEMPTED;
+ }
+
if (log.isTraceEnabled()) {
log.trace("try oauth");
}
@@ -137,6 +142,7 @@ public abstract class RequestAuthenticator {
protected abstract void completeOAuthAuthentication(KeycloakPrincipal principal);
protected abstract void completeBearerAuthentication(KeycloakPrincipal principal, String method);
protected abstract String getHttpSessionId(boolean create);
+ protected abstract boolean isAuthenticationRequired();
protected void completeAuthentication(BearerTokenRequestAuthenticator bearer, String method) {
RefreshableKeycloakSecurityContext session = new RefreshableKeycloakSecurityContext(deployment, null, bearer.getTokenString(), bearer.getToken(), null, null, null);
diff --git a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java
index 0556b01e01..7e90aefc2f 100755
--- a/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java
+++ b/integration/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/JettyRequestAuthenticator.java
@@ -82,4 +82,9 @@ public class JettyRequestAuthenticator extends RequestAuthenticator {
}
+ @Override
+ protected boolean isAuthenticationRequired() {
+ //TODO: find out if authentication is required
+ return true;
+ }
}
diff --git a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
index 58989ef4d0..356c4a5654 100755
--- a/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
+++ b/integration/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
@@ -90,4 +90,10 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator {
HttpSession session = request.getSession(create);
return session != null ? session.getId() : null;
}
+
+ @Override
+ protected boolean isAuthenticationRequired() {
+ //TODO: find out if authentication is required
+ return true;
+ }
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowKeycloakAuthMech.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowKeycloakAuthMech.java
index 1e49be9f18..9a35896122 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowKeycloakAuthMech.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowKeycloakAuthMech.java
@@ -103,7 +103,6 @@ public abstract class AbstractUndertowKeycloakAuthMech implements Authentication
if (outcome == AuthOutcome.FAILED) {
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
-
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
index f154ba3698..26be6378dc 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
@@ -87,4 +87,9 @@ public abstract class AbstractUndertowRequestAuthenticator extends RequestAuthen
* @return The account
*/
protected abstract KeycloakUndertowAccount createAccount(KeycloakPrincipal principal);
+
+ @Override
+ protected boolean isAuthenticationRequired() {
+ return securityContext.isAuthenticationRequired();
+ }
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
index 2c7ece02ba..0ae5b6eb78 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java
@@ -49,7 +49,7 @@ public class ServletKeycloakAuthMech extends AbstractUndertowKeycloakAuthMech {
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
UndertowHttpFacade facade = new UndertowHttpFacade(exchange);
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
- if (!deployment.isConfigured() || !securityContext.isAuthenticationRequired()) {
+ if (!deployment.isConfigured()) {
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}