OKTA Invalid Scope issue s - okta-api

I am trying to use OKTa for APP to APP authentication inside a SpringBoot Application and I get the below Scope issues ,
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad
Request: [{"error":"invalid_scope","error_description":"One or more scopes
are not configured for the authorization server resource."}]
we have default custome_scope mentioned at the Okta sever and when I try using the below code I am getting error while accesing line no 5 : in the below code snippet ,
String tokenUri = issuerUri + "/v2/token" + "? grant_type=client_credentials&response_type=token&scope=read";
RestTemplate rt = new RestTemplate();
headers = setHeaders(clientId, clientSecret, headers);
HttpEntity requestEntity = new HttpEntity(headers);
TokenData response = rt.postForObject(tokenUri, requestEntity, TokenData.class);
Can anyone help me

Related

How to make a call from standard python GAE app to google function with authentication?

I have a google function with removed allUsers permission.
I have a standard GAE application written in Python.
How to get proper auth token to make http call to the protected google function?
auth_token, _ = app_identity.get_access_token('https://www.googleapis.com/auth/cloud-platform')
headers = {'Authorization': 'Bearer {}'.format(auth_token)}
result = urlfetch.fetch(
url='https://us-central1-app_id.cloudfunctions.net/function-name',
method=urlfetch.POST,
headers=headers)
It looks like there are some answers here https://cloud.google.com/functions/docs/securing/authenticating but I could not figure out how to make it working.
Thank you in advance
I have followed the documentation you sent and tried to reproduce. I have used this sample for function to function and it worked fine for me. These are the lines within the sample code where the token is obtained:
metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_request_url = metadata_server_token_url + receiving_function_url
token_request_headers = {'Metadata-Flavor': 'Google'}
# Fetch the token
token_response = requests.get(token_request_url, headers=token_request_headers)
jwt = token_response.content.decode("utf-8")

Unity/Android ServerAuthCode has no idToken on Backend

I have an unity app and use the google-play-games plugin with google *.aar versions 9.4.0. I lately changed my Backend (Google App Engine) from php to java. My problem is the following: in php the serverauthcode is used to get the users data (in JWT format) - it was working fine. So I changed to a Java servlet and I am failing since 2 days to get a valid idtoken. I am able to recieve the server auth code from my app and a valid token response is made by GoogleAuthorizationCodeTokenRequest (see code snippet). Unfortunately it does not contain any idtoken content but a valid auth_token. So I can not get the user id to identifiy the user. When I call tokenResponse.parseIdToken(); it is failing with a NullPointerException.
servlet code (authCode is the serverAuthCode I send from the play-games-plugin inside Unity to my GAE):
// (Receive authCode via HTTPS POST)
// Set path to the Web application client_secret_*.json file you downloaded from the
// Google Developers Console: https://console.developers.google.com/apis/credentials?project=_
// You can also find your Web application client ID and client secret from the
// console and specify them directly when you create the GoogleAuthorizationCodeTokenRequest
// object.
String CLIENT_SECRET_FILE = "/mypath/client_secret.json";
// Exchange auth code for access token
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(
JacksonFactory.getDefaultInstance(), new FileReader(CLIENT_SECRET_FILE));
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
clientSecrets.getDetails().getTokenUri(),
clientSecrets.getDetails().getClientId(),
clientSecrets.getDetails().getClientSecret(),
authCode,
REDIRECT_URI) // Specify the same redirect URI that you use with your web
// app. If you don't have a web version of your app, you can
// specify an empty string.
.execute();
String accessToken = tokenResponse.getAccessToken();
// Get profile info from ID token -> HERE IT THROWS AN EXCEPTION.
GoogleIdToken idToken = tokenResponse.parseIdToken();
GoogleIdToken.Payload payload = idToken.getPayload();
String userId = payload.getSubject(); // Use this value as a key to identify a user.
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
the token response looks like (its invalid now):
{
"access_token" : "ya29.CjA8A7O96w-vX4OCSPm-GMEPGVIEuRTeOxKy_75z6fbYVSXsdi9Ot3NmxlE-j_t-BI",
"expires_in" : 3596,
"token_type" : "Bearer"
}
In my PHP GAE I always had a idToken inside this constuct which contained my encrypted data. But it is missing now?! So I asssume I do somthing differently in Java or I made a mistake creating the new OAuth 2.0 Client on the google console.
I checked the accessToken manually via:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.CjA8A7O96w-vX4OCSPm-GMEPGVIEu-RTeOxKy_75z6fbYVSXsdi9Ot3NmxlE-j_t-BI
{
"issued_to": "48168146---------.apps.googleusercontent.com",
"audience": "48168146---------.apps.googleusercontent.com",
"scope": "https://www.googleapis.com/auth/games_lite",
"expires_in": 879,
"access_type": "offline"
}
Is there something I do not see? Help is very much appreciated...
I found a root cause discussion inside the unity plugin "play-games-services" on github:
https://github.com/playgameservices/play-games-plugin-for-unity/issues/1293
and
https://github.com/playgameservices/play-games-plugin-for-unity/issues/1309
It seems that google switching their authentication flow. In the given links they are talking about adding the email scope inside the plugin to get the idtoken again. I'll try that in the next days and share my experience.
Here is a good explaination about what happens:
http://android-developers.blogspot.de/2016/01/play-games-permissions-are-changing-in.html
If you do what paulsalameh said here (Link to Github) it will work again:
paulsalameh: Sure. After you import the unitypackage, download NativeClient.cs and
PlayGamesClientConfig.cs from my commits (#1295 & #1296), and replace
them in the correct locations.
Afte that "unity play-services-plugin" code update you will be able to add AddOauthScope("email") to PlayGamesClientConfiguration, which allows your server to get the idtoken with the serverAuthCode again...
Code snippet from Unity:
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
.AddOauthScope("email")
.AddOauthScope("profile")
.Build();
Now I am back in business:
{
"access_token" : "ya29.Ci8..7kBR-eBdPw1-P7Pe8QUC7e_Zv7qxCHA",
"expires_in" : 3600,
"id_token" : "eyJhbGciOi......I1NiE0v6kqw",
"refresh_token" : "1/HlSZOo......dQV1y4E",
"token_type" : "Bearer"
}

Accessing authenticated Google Cloud Endpoints API from Google Apps Script

I'm trying to pull some data into a Google sheets spreadsheet from an API that's been built using Google Cloud Endpoints. Here is the API declaration:
#Api(
name = "myendpoint",
namespace =
#ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)
The method I'm trying to access has authentication enabled by means of the user parameter in the API declaration:
#ApiMethod(name = "ping", httpMethod = HttpMethod.GET, path = "ping")
public StringResponse getPing(User user) throws OAuthRequestException {
CheckPermissions(user);//throws an exception if the user is null or doesn't have the correct permissions
return new StringResponse("pong");
}
This works fine when using the generated client libraries or the gapi js library. However AFAIK I can't use those js libraries in Apps Script.
I've got an OAuth2 flow working using the apps-script-oauth2 library from here, and I'm pretty much using the default setup for creating the service
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService(SERVICE_NAME)
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('ruggedAuthCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
.setScope(SCOPES)
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', Session.getActiveUser().getEmail())
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
.setParam('approval_prompt', 'auto')
//.setParam('include_granted_scopes', 'true');
}
These are my methods for accessing the APIs
function getDriveDocs() {
return executeApiMethod('https://www.googleapis.com/drive/v2/','files?maxResults=10');
}
function pingServer(){
return executeApiMethod('https://myapp.appspot.com/_ah/api/myendpoint/v1/','ping');
}
function executeApiMethod(apiUrl, method)
{
//var url = ;
var url = apiUrl + method;
var service = getRuggedService();
return UrlFetchApp.fetch(url, {
'muteHttpExceptions': true,
'method': 'get',
'headers': {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
}
The getDriveDocs() method works perfectly, so I know my auth flow is working correctly. Also, if I call an unauthenticated method in my API I get the correct response. However, when I call the authenticated 'ping' method, the 'user' parameter is always null. Am I missing something in the fetch call? Everything I've read so far seems to suggest that setting
Authorization: 'Bearer ' + service.getAccessToken()
should be enough.
Any help would be much appreciated!
This turned out to be a simple mistake - I had created a new oauth2 credential in the google dev console and had not added the new client id to the API declaration. Here is the working API declaration:
#Api(
name = "myendpoint",
namespace =
#ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID, GAPPS_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)

Salesforce Oauth Status Code 302

While trying to setup oauth in the org, getting status code 302.
Below is the code snippet.
String AUTH_URL = 'https://login.salesforce.com/services/oauth2/authorize';
String redirect_uri = 'https://login.salesforce.com/services/oauth2/success';
String response_type = 'token';
String client_id = 'xxxxxxxxxxxxxx.xxxxxxxxx';
authURL = AUTH_URL +
'?response_type=' + response_type +
'&client_id=' + client_id +
'&redirect_uri=' + redirect_uri;
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setMethod('GET');
req.setEndpoint(authUrl);
res = http.send(req);
//RESULT:
res.getStatusCode() = 302
res.getStatus() = Found
I am expecting to receive access Token and refresh token in response's body but it is empty.
Please suggest if I am missing out on something.
Thanks in advance.
the authorize endpoint is for a browser based interactive login, not a programatic login. If you want a pure programatic method, then you should checkout the username/password oauth flow that you can use via the /services/oauth2/token endpoint.

How to authenticate programmatically to google app engine (with Java)?

I'm trying to authenticate to google app engine programmatically.
I've tried the code sample from the "gae-app-manager" project but it fails:
tmp>java -jar net.sf.gae-app-manager-0.0.1-jar-with-dependencies.jar myaccount#gmail.com mypassword appname
Exception in thread "main" java.lang.Exception: Did not find ACSID cookie
at net.sf.gaeappmanager.google.LogonHelper.loginToGoogleAppEngine(LogonHelper.java:85)
at net.sf.gaeappmanager.google.appengine.Manager.retrieveAppQuotaDetails(Manager.java:34)
at net.sf.gaeappmanager.google.appengine.Main.main(Main.java:55)
Any idea? I'm able to get the token, but there are no cookies.
The code (taken from the gae-app-manager project - http://gae-app-manager.git.sourceforge.net/git/gitweb.cgi?p=gae-app-manager/gae-app-manager;a=blob;f=src/main/java/net/sf/gaeappmanager/google/LogonHelper.java;h=8e09a6d7f864c29b10847ac7fd2eeab2d3e561e6;hb=HEAD):
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accountType", "HOSTED_OR_GOOGLE"));
nvps.add(new BasicNameValuePair("Email", userid));
nvps.add(new BasicNameValuePair("Passwd", password));
nvps.add(new BasicNameValuePair("service", "ah"));
nvps.add(new BasicNameValuePair("source", source));
HttpPost post = new HttpPost(
"https://www.google.com/accounts/ClientLogin");
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() != 200) {
throw new Exception("Error obtaining ACSID");
}
String authToken = getAuthToken(response.getEntity().getContent());
post.abort();
HttpGet get = new HttpGet(
"https://appengine.google.com/_ah/login?auth=" + authToken);
response = client.execute(get);
for (Cookie cookie : client.getCookieStore().getCookies()) {
if (cookie.getName().startsWith("ACSID")) {
return cookie.getValue();
}
}
get.abort();
throw new Exception("Did not find ACSID cookie");
Thanks,
Li
Have you considered using the OAuth support instead of trying to log in as a web client would? Every App Engine app can act as an OAuth provider with very little work required on the server side to set it up.
To solve the problem use "SACSID" instead of "ACSID"

Resources