[OPENAM-6976] OAuth2 Error Page on oauth2/authorize with valid params and cookie Created: 29/Sep/15  Updated: 15/Dec/15  Resolved: 30/Sep/15

Status: Resolved
Project: OpenAM
Component/s: oauth2, OpenID Connect
Affects Version/s: 13.0.0
Fix Version/s: 13.0.0

Type: Bug Priority: Blocker
Reporter: hadi hahmadi Assignee: James Phillpotts
Resolution: Fixed Votes: 0
Labels: 13.0.0-Must-Fix, AME, TESLA, release-notes
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

EC2 Ubuntu 64 VM, Tomcat 7, JDK 1.7, OpenAM 13.0.0-SNAPSHOT Build ${svn-revision.revision} (2015-September-28 15:34)


Target Version/s:
Sprint: Sprint 95 - Team Tesla

 Description   

Created OAuth2 provider and registered a client app as an OAuth2 agent, and configured required scopes.

Tried to access the oauth2/authorize page after being authenticated, it returns the "OAuth2 Error Page".

More precisely, the following request (with a valid Cookie):
curl --header "Cookie: ****" https://openam.example.com/openam/oauth2/authorize?response_type=code\&scope=openid%20email\&client_id=XXXX\&redirect_uri=YYYY\&nonce=ZZZZ

returns 400 with the following response content:

<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="OAuth2 Error">
<title>OAuth2 Error Page</title>
</head>

<body>
<div id="wrapper" class="hidden">Loading...</div>
<footer id="footer" class="footer hidden"></footer>
<script type="text/javascript">
pageData = {
baseUrl: "https://protectserve.openrock.org:8043/openam/XUI",
error:

{ description: "Internal Server Error", message: "server_error" }

}
</script>
<script data-main="https://protectserve.openrock.org:8043/openam/XUI/main-authorize" src="https://protectserve.openrock.org:8043/openam/XUI/libs/requirejs-2.1.14-min.js"></script>
</body>
</html>

    • I tried multiple response types, scopes, etc. Same error is observed.


 Comments   
Comment by Peter Major [X] (Inactive) [ 29/Sep/15 ]

May have the same root cause as OPENAM-6967.

Comment by Rich Riley [X] (Inactive) [ 29/Sep/15 ]

This might be because you don't have a "display name" or "display description" set on your oauth2 client. This will be fixed soon as a result of the work done on - OPENAM-6931

Comment by hadi hahmadi [ 29/Sep/15 ]

Made sure both "display name" and "display description" are set in the client config. But same error page.

Comment by Dirk Hogan [ 30/Sep/15 ]

I've spent the day fruitlessly attempting to get an OIDC token via the implicit flow. Also nothing relevant in the logs. After a day of debugging, I seem to be hanging up on the evaluation of the default OIDC claims script. This happens on line 147 of OpenAMScopeValidator. It seems that the default script contains an error - I get:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.forgerock.oauth2.core.UserInfoClaims
which is not caught by the ScriptException catch block surrounding the script execution, and is propagated outward and ultimately caught and propagated as a BadRequest exception (in my case).

If I change the ScriptException catch block to catch Exception (which will log the exception - and probably a good idea when running a potentially 'foreign' script), I see this in the logs:
Error running OIDC claims script
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.forgerock.oauth2.core.UserInfoClaims
at org.forgerock.openam.oauth2.OpenAMScopeValidator.getUserInfo(OpenAMScopeValidator.java:247)
at org.forgerock.openam.oauth2.OpenAMOAuth2ProviderSettings.getUserInfo(OpenAMOAuth2ProviderSettings.java:448)
at org.forgerock.openam.oauth2.OpenAMTokenStore.appendIdTokenClaims(OpenAMTokenStore.java:282)
at org.forgerock.openam.oauth2.OpenAMTokenStore.createOpenIDToken(OpenAMTokenStore.java:267)
at org.forgerock.openidconnect.IdTokenResponseTypeHandler.handle(IdTokenResponseTypeHandler.java:62)
at org.forgerock.restlet.ext.oauth2.flow.responseTypes.IDTokenResponseType.createToken(IDTokenResponseType.java:72)
at org.forgerock.openam.oauth2.legacy.LegacyResponseTypeHandler.handle(LegacyResponseTypeHandler.java:77)

I am not sure that your flow will trigger the same script execution, but this may be the case.

James Phillpotts, if the error above is unrelated to the current issue, I'd be happy to file another one.

Comment by James Phillpotts [ 30/Sep/15 ]

Hi Dirk, at a guess, you're using the latest trunk build with an upgraded set of SMS content, which includes the old OIDC claims script. You can either do a fresh install or replace the claims script with the one from trunk. hadi hahmadi is there any chance this is your problem? I'm just starting to look at this bug now.

Comment by hadi hahmadi [ 30/Sep/15 ]

Hi Dirk and James, FYI, I replaced the oidc claim script with the trunk version as in the above link, yet same "OAuth2 Error Page".

Comment by hadi hahmadi [ 30/Sep/15 ]

Well, I played with the log levels and observed the following:

  • when server debugging level = error, no logs and "OAuth2 Error Page" in UI
  • when server debugging level = warning, no logs and the following message in the UI:
    Error:

The OpenID Connect Provider returned an error: not_found
Description:

Error running OIDC claims script: java.util.concurrent.ExecutionException: javax.script.ScriptException: javax.script.ScriptException: java.lang.SecurityException: Access to Java class "org.codehaus.groovy.runtime.GStringImpl" is prohibited.

  • when server debugging level = message, the same UI message and the following in the OAuth2Provider debug file:
    OAuth2Provider:09/30/2015 02:02:04:349 PM UTC: Thread[http-bio-8043-exec-11,5,main]: TransactionId[849043b5-6775-4198-bea7-84fa857848ac]
    Error running OIDC claims script
    javax.script.ScriptException: java.util.concurrent.ExecutionException: javax.script.ScriptException: javax.script.ScriptException: java.lang.SecurityException: Access to Java class "org.codehaus.groovy.runtime.GStringImpl" is prohibited.
    at org.forgerock.openam.scripting.ThreadPoolScriptEvaluator.evaluateScript(ThreadPoolScriptEvaluator.java:98)
    at org.forgerock.openam.oauth2.OpenAMScopeValidator.getUserInfo(OpenAMScopeValidator.java:247)
    at org.forgerock.openam.oauth2.OpenAMOAuth2ProviderSettings.getUserInfo(OpenAMOAuth2ProviderSettings.java:448)
    at org.forgerock.oauth2.core.AuthorizationServiceImpl.authorize(AuthorizationServiceImpl.java:130)
    at org.forgerock.oauth2.restlet.AuthorizeResource.authorize(AuthorizeResource.java:95)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    ....

Hope that helps.
Thanks,
Hadi

Comment by James Phillpotts [ 30/Sep/15 ]

You should be able to add that class to the global configuation for OIDC scripts in the scripting service as a white listed class name.

Is your OIDC claims script modified from the default one? I've just tried this out now and don't get the error you describe.

Comment by James Phillpotts [ 30/Sep/15 ]

Anyway, I will add that class to the default list of whitelisted classes.

Comment by hadi hahmadi [ 30/Sep/15 ]

I haven't modified the claims script, just copied the extact file content. Having whitelisted the class, I am back to the behavior I used to observe in the first place (with the older script - in the main post), and still in message debug level, I see only:

OAuth2Provider:09/30/2015 02:36:52:907 PM UTC: Thread[http-bio-8043-exec-26,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
Existing saved consent value for resourceOwner: alice in attribute:savedConsentAttribute in realm:/ is:[]
OAuth2Provider:09/30/2015 02:36:52:950 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: zip
OAuth2Provider:09/30/2015 02:36:52:951 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: uma_protection
OAuth2Provider:09/30/2015 02:36:52:952 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: ehr
OAuth2Provider:09/30/2015 02:36:52:952 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: state
OAuth2Provider:09/30/2015 02:36:52:953 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: city
OAuth2Provider:09/30/2015 02:36:52:953 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: mobilephone
OAuth2Provider:09/30/2015 02:36:52:953 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
OpenAMScopeValidator.getUserInfo()::Message: scope not bound to claims: uma_authorization
OAuth2Provider:09/30/2015 02:36:53:016 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
WARNING: OpenAMScopeValidator.getUserInfo(): Got an empty result for claim=zoneinfo
OAuth2Provider:09/30/2015 02:36:53:030 PM UTC: Thread[pool-10-thread-4,5,main]: TransactionId[4363cb11-6b7f-4391-b6a8-4e96a7fea6dd]
WARNING: OpenAMScopeValidator.getUserInfo(): Got an empty result for claim=locale

I even tried turning off "Use system SecurityManager" in the oidc scripting config, but no change.

Comment by James Phillpotts [ 30/Sep/15 ]

Oh, sorry - I misunderstood that the GStringImpl problem was the original issue!

Comment by James Phillpotts [ 30/Sep/15 ]

I've just tried this again, this time doing exactly as you did using curl rather than the browser, and I get the expected consent page content:

$ curl --header "Cookie: iPlanetDirectoryPro=AQIC5wM2LY4Sfcwq9VLko8_wduFjGXcPyCz4tmTssHjNLPw.*AAJTSQACMDEAAlNLABM4NTI3MzAzNjQ0Njg0NTk0ODA0AAJTMQAA*" 'http://local.example.com:18080/openam/oauth2/authorize?response_type=code&scope=openid%20email&client_id=fred&redirect_uri=http:%2F%2Fgoogle.com&nonce=1234'
<!DOCTYPE html>
<!--
  ~ DO NOT REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  ~
  ~ Copyright 2012-2015 ForgeRock AS.
  ~
  ~ The contents of this file are subject to the terms
  ~ of the Common Development and Distribution License
  ~ (the License). You may not use this file except in
  ~ compliance with the License.
  ~
  ~ You can obtain a copy of the License at
  ~ http://forgerock.org/license/CDDLv1.0.html
  ~ See the License for the specific language governing
  ~ permission and limitations under the License.
  ~
  ~ When distributing Covered Code, include this CDDL
  ~ Header Notice in each file and include the License file
  ~ at http://forgerock.org/license/CDDLv1.0.html
  ~ If applicable, add the following below the CDDL Header,
  ~ with the fields enclosed by brackets [] replaced by
  ~ your own identifying information:
  ~ "Portions Copyrighted [year] [name of copyright owner]"
  ~
  ~ Portions Copyrighted 2014 Nomura Research Institute, Ltd
  -->
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="OAuth2 Authorization">
        <title>OAuth2 Authorization Server</title>
    </head>

    <body style="display:none">
        <div id="wrapper">Loading...</div>
        <footer id="footer" class="footer"></footer>
        <script type="text/javascript">
            pageData = {
                realm: "/",

                baseUrl : "http://local.example.com:18080/openam/XUI",
                oauth2Data: {
                    redirectUri: "http://google.com",
                    scope: "openid email",

                    nonce: "1234",

                    displayDescription: "fredy",
                    responseType: "code",
                    clientId: "fred",
                    formTarget: "/openam/oauth2/authorize?response_type=code&scope=openid%20email&client_id=fred&redirect_uri=http:%2F%2Fgoogle.com&nonce=1234",
                    displayName: "Fred",
                    userName: "demo",

                    displayScopes: [ { "name": "Your email address", "values": { "Email address": "demo&#x40;example.com" } } ],
                    displayClaims: [  ]
                }
            };
        </script>
        <script data-main="http://local.example.com:18080/openam/XUI/main-authorize" src="http://local.example.com:18080/openam/XUI/libs/requirejs-2.1.14-min.js"></script>
    </body>
</html>

Are there any other details you could provide that might help me work out why it's behaving differently for you?

Comment by hadi hahmadi [ 30/Sep/15 ]

Thanks for the update James. I tried the request with different scope combinations, and found out the profile and phone are causing issues for me. I will update you more about if this is particular to my use case and or general issue with the corresponding mapping.

Comment by hadi hahmadi [ 30/Sep/15 ]

The only exclusive and common about those attrs is in using '_' for the map value, like 'phone_number' and 'first_name'. Just an observation, but not a technical guess

Comment by James Phillpotts [ 30/Sep/15 ]

Ah, great. I'll resolve the issue for the moment - please feel free to open another one if you work out more specifics.

Comment by hadi hahmadi [ 30/Sep/15 ]

Sure, thanks.
P.S. It wasn't '_' issue....

Comment by hadi hahmadi [ 30/Sep/15 ]

Although the curl command worked the returned html body was something like this. Please note that there''s no javascript for page data and the HTML is already rendered. Also note that no scope is passed to the consent list and (maybe hence) the form is hidden!!! (Using OpenAM 13.0.0-SNAPSHOT Build ${svn-revision.revision} (2015-September-28 15:34) )

curl --header "Cookie: ****" 'https://openam.example.com/openam/oauth2/authorize?response_type=code&scope=openid%20email&client_id=fred&redirect_uri=http:%2F%2Fgoogle.com&nonce=1234'

<!doctype html>
<!--
  ~ DO NOT REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  ~
  ~ Copyright 2012-2015 ForgeRock AS.
  ~
  ~ The contents of this file are subject to the terms
  ~ of the Common Development and Distribution License
  ~ (the License). You may not use this file except in
  ~ compliance with the License.
  ~
  ~ You can obtain a copy of the License at
  ~ http://forgerock.org/license/CDDLv1.0.html
  ~ See the License for the specific language governing
  ~ permission and limitations under the License.
  ~
  ~ When distributing Covered Code, include this CDDL
  ~ Header Notice in each file and include the License file
  ~ at http://forgerock.org/license/CDDLv1.0.html
  ~ If applicable, add the following below the CDDL Header,
  ~ with the fields enclosed by brackets [] replaced by
  ~ your own identifying information:
  ~ "Portions Copyrighted [year] [name of copyright owner]"
  ~
  ~ Portions Copyrighted 2014 Nomura Research Institute, Ltd
  -->
<html lang="en">
    <head>
        <title>OAuth2 Authorization Server</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" charset="utf-8"/>
        <meta name="description" content="OAuth2 Authorization">
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
        <link href='http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,700,700italic' rel='stylesheet' type='text/css'>
                    <style>
                .hidden {
                    display: none;
                }
                ul.scopes {
                    margin-top: -10px;
                }
                ul.scopes li {
                    padding-top: 10px;
                    padding-left: 20px;
                    font-size: 0.9em;
                    list-style-position: inside;
                    list-style-type: disc;
                }
                hr {
                    margin: 15px 0;
                }
            </style>
            <script type="text/javascript">
                realm = "/";
                less = {
                rootPath: "https://openam.example.com:443/openam/XUI"
            };
            </script>
            <script data-main="https://openam.example.com:443/openam/XUI/main-authorize" src="https://openam.example.com:443/openam/XUI/libs/requirejs-2.1.14-min.js"></script>
    </head>
    <body>
        <div id="wrapper">
            <div id="login-base" class="container hidden">
                    <div style="margin: 0 auto; margin-top: 50px;">
                        <div style="background-color: #4787ed; width: 128px; height: 128px; margin-left: auto; margin-right: auto; padding: 15px; border-radius: 0; display: table;">
                           <div style="display: table-cell; vertical-align: middle; padding: 0; color: #fff; font-size: 18px; font-weight: 600; text-align: center;">
			    <i class="fa fa-shield" style="font-size: 44px; margin-bottom: 0px;"></i>
			    <br>
			    UProtect
			   </div>
			</div>
                    </div>
              <!-- div id="content" class="content" -->
              <div style="margin: 0 auto; margin-top: 5px;">
                  <div id="login-container" class="col-sm-6 col-sm-offset-3">
                      <div id="oauth-header" class="page-header">
                          <section id="intro" class="text-center">
                              <h1>fred</h1>
                              <div>fred wants to see this </div>
                          </section>
                      </div>
                      <form action="/openam/oauth2/authorize?response_type=code&scope=openid%20email&client_id=fred&redirect_uri=http:%2F%2Fgoogle.com&nonce=1234" method="post" class="clearfix">
                          <!-- div>This application is requesting the following private information:</div -->
                          <br/>
                          <!-- Optional parameters -->
                              <input type="hidden" name="realm" value="/"/>
                              <input type="hidden" name="redirect_uri" value="http://google.com"/>
                              <input type="hidden" name="scope" value="openid email"/>
                              <input type="hidden" name="nonce" value="1234"/>
                          <!-- Required parameters -->
                          <input type="hidden" name="response_type" value="code"/>
                          <input type="hidden" name="client_id" value="fred"/>

                          <div class="checkbox">
                              <label>
                                  <input type="checkbox" name="save_consent"/> Save Consent
                              </label>
                          </div>

                          <div class="pull-right">
                              <input type="submit" name="decision" class="btn btn-primary" value="Allow"/>
                              <input type="submit" name="decision" class="btn btn-default" value="Deny"/>
                          </div>
                      </form>
                    </div>
                </div>
            </div>
        </div>
        <footer id="footer" class="footer">
            <div class="container">
                <p>
                    <a href="mailto: info@forgerock.com">info@forgerock.com</a>
                    <br>
                    Copyright © 2010-15 ForgeRock AS, all rights reserved.
                </p>
            </div>
        </footer>
    </body>
</html>
Comment by James Phillpotts [ 30/Sep/15 ]

That's curious. The page almost looks right, but this block is wrong:

            <script type="text/javascript">
                realm = "/";
                less = {
                rootPath: "https://openam.example.com:443/openam/XUI"
            };
            </script>

I saw you edited your comment once - is that block definitely as it comes from the server? Note that as you've got the <div id="wrapper"> this means you have the post-javascript source, not the source as delivered from the server.

Comment by hadi hahmadi [ 30/Sep/15 ]

The edit was to change the servername from real to openam.example.com. This was the direct response from the server.

Comment by hadi hahmadi [ 02/Oct/15 ]

James, this was the result of a bug in our install script, which I was not aware of. Haven't located the bug yet, but tried a Vanilla install and OAuth2 works there as promised. Thanks again.

Generated at Sat Oct 24 00:04:34 UTC 2020 using Jira 7.13.12#713012-sha1:6e07c38070d5191bbf7353952ed38f111754533a.