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.source} + ${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; }