keycloak-aplcache

Merge pull request #4243 from mposolda/KEYCLOAK-3316 KEYCLOAK-3316

6/20/2017 5:05:23 PM

Details

diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index 26d012b..3a7e4c0 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -269,6 +269,12 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
     }
 
     private Response checkOIDCParams() {
+        // If request is not OIDC request, but pure OAuth2 request and response_type is just 'token', then 'nonce' is not mandatory
+        boolean isOIDCRequest = TokenUtil.isOIDCRequest(request.getScope());
+        if (!isOIDCRequest && parsedResponseType.toString().equals(OIDCResponseType.TOKEN)) {
+            return null;
+        }
+
         if (parsedResponseType.isImplicitOrHybridFlow() && request.getNonce() == null) {
             ServicesLogger.LOGGER.missingParameter(OIDCLoginProtocol.NONCE_PARAM);
             event.error(Errors.INVALID_REQUEST);
@@ -354,10 +360,12 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
 
     private void checkRedirectUri() {
         String redirectUriParam = request.getRedirectUriParam();
+        boolean isOIDCRequest = TokenUtil.isOIDCRequest(request.getScope());
 
         event.detail(Details.REDIRECT_URI, redirectUriParam);
 
-        redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUriParam, realm, client);
+        // redirect_uri parameter is required per OpenID Connect, but optional per OAuth2
+        redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUriParam, realm, client, isOIDCRequest);
         if (redirectUri == null) {
             event.error(Errors.INVALID_REDIRECT_URI);
             throw new ErrorPageException(session, Messages.INVALID_PARAMETER, OIDCLoginProtocol.REDIRECT_URI_PARAM);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
index 60f5493..c61bdd0 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
@@ -26,6 +26,7 @@ import org.keycloak.services.Urls;
 
 import javax.ws.rs.core.UriInfo;
 import java.net.URI;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -38,12 +39,16 @@ public class RedirectUtils {
 
     public static String verifyRealmRedirectUri(UriInfo uriInfo, String redirectUri, RealmModel realm) {
         Set<String> validRedirects = getValidateRedirectUris(uriInfo, realm);
-        return verifyRedirectUri(uriInfo, null, redirectUri, realm, validRedirects);
+        return verifyRedirectUri(uriInfo, null, redirectUri, realm, validRedirects, true);
     }
 
     public static String verifyRedirectUri(UriInfo uriInfo, String redirectUri, RealmModel realm, ClientModel client) {
+        return verifyRedirectUri(uriInfo, redirectUri, realm, client, true);
+    }
+
+    public static String verifyRedirectUri(UriInfo uriInfo, String redirectUri, RealmModel realm, ClientModel client, boolean requireRedirectUri) {
         if (client != null)
-            return verifyRedirectUri(uriInfo, client.getRootUrl(), redirectUri, realm, client.getRedirectUris());
+            return verifyRedirectUri(uriInfo, client.getRootUrl(), redirectUri, realm, client.getRedirectUris(), requireRedirectUri);
         return null;
     }
 
@@ -69,10 +74,16 @@ public class RedirectUtils {
         return redirects;
     }
 
-    private static String verifyRedirectUri(UriInfo uriInfo, String rootUrl, String redirectUri, RealmModel realm, Set<String> validRedirects) {
+    private static String verifyRedirectUri(UriInfo uriInfo, String rootUrl, String redirectUri, RealmModel realm, Set<String> validRedirects, boolean requireRedirectUri) {
         if (redirectUri == null) {
-            logger.debug("No Redirect URI parameter specified");
-            return null;
+            if (!requireRedirectUri) {
+                redirectUri = getSingleValidRedirectUri(validRedirects);
+            }
+
+            if (redirectUri == null) {
+                logger.debug("No Redirect URI parameter specified");
+                return null;
+            }
         } else if (validRedirects.isEmpty()) {
             logger.debug("No Redirect URIs supplied");
             redirectUri = null;
@@ -149,4 +160,14 @@ public class RedirectUtils {
         return false;
     }
 
+    private static String getSingleValidRedirectUri(Collection<String> validRedirects) {
+        if (validRedirects.size() != 1) return null;
+        String validRedirect = validRedirects.iterator().next();
+        int idx = validRedirect.indexOf("/*");
+        if (idx > -1) {
+            validRedirect = validRedirect.substring(0, idx);
+        }
+        return validRedirect;
+    }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/ServicesLogger.java b/services/src/main/java/org/keycloak/services/ServicesLogger.java
index bd239a6..2d6c473 100644
--- a/services/src/main/java/org/keycloak/services/ServicesLogger.java
+++ b/services/src/main/java/org/keycloak/services/ServicesLogger.java
@@ -406,7 +406,7 @@ public interface ServicesLogger extends BasicLogger {
     void failedToCloseProviderSession(@Cause Throwable t);
 
     @LogMessage(level = WARN)
-    @Message(id=91, value="Request is missing scope 'openid' so it's not treated as OIDC, but just pure OAuth2 request. This can have impact in future versions (eg. removed IDToken from the Token Response)")
+    @Message(id=91, value="Request is missing scope 'openid' so it's not treated as OIDC, but just pure OAuth2 request.")
     @Once
     void oidcScopeMissing();
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
index 4c89eaa..207a317 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
@@ -102,7 +102,7 @@ public class OAuthClient {
 
     private String maxAge;
 
-    private String responseType = OAuth2Constants.CODE;
+    private String responseType;
 
     private String responseMode;
 
@@ -171,6 +171,8 @@ public class OAuthClient {
         clientSessionState = null;
         clientSessionHost = null;
         maxAge = null;
+        responseType = OAuth2Constants.CODE;
+        responseMode = null;
         nonce = null;
         request = null;
         requestUri = null;