Remove offline_access scope in identity server 4 we;;-known configuration - .net-core

I have .NET Core app with IdentityServer 4 in it.
I want to hide/remove one entry of "scopes_supported" under .well-known/openid-configuration endpoint.
Basically it shows all my custom scopes, but one is automatically generated, maybe anyone can help me hiding it?
....
"scopes_supported": [
"openid",
"profile",
"custom_scope1",
"custom_scope2",
"offline_access" // <----- this one worries me, how to remove it
],
....

The code for the discovery document creation that adds the offline_Access scope is found here.
If you disable the Options.Discovery.ShowApiScopes flag, then it will not be shown, but you won't see the ApiScopes either it seems.
See this page for how to disable that flag or you disable it as shown below.
services.AddIdentityServer(options =>
{
options.Discovery.ShowIdentityScopes = false;
options.Discovery.ShowApiScopes = false;
options.Discovery.ShowClaims = false;
options.Discovery.ShowExtensionGrantTypes = false;
});
It seems you can't just hide the offline_scope.

Related

How to use Sign-In User ID to send push notifications

I have some users signed into my actions-on-google app via Google Sign-In ( https://developers.google.com/actions/identity/google-sign-in )
I want to sent push notifications to one of those users.
For getting push notifications work with actions in the first place, I tried this sample: https://github.com/actions-on-google/dialogflow-updates-nodejs/blob/master/functions/index.js but I only can get this to work without this commit: https://github.com/actions-on-google/dialogflow-updates-nodejs/commit/c655062047b49e372da37af32376bd06d837fc7f#diff-1e53ef2f51bd446c876676ba83d7c888
It works fine, but I think const userID = conv.user.id; returns the deprecated Anonymous User ID. The commit suggests to use const userID = conv.arguments.get('UPDATES_USER_ID'); which returns undefined.
I use this nodejs code to send the push notifications.
const request = require('request');
const {JWT} = require('google-auth-library');
const serviceAccount = require('./service-account.json');
let jwtClient = new JWT(
serviceAccount.client_email, null, serviceAccount.private_key,
['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
null
);
jwtClient.authorize((authErr, tokens) => {
let notification = {
userNotification: {
title: process.argv[2],
},
target: {
userId: USERID,
intent: 'tell_latest_status',
// Expects a IETF BCP-47 language code (i.e. en-US)
locale: 'en-US'
},
};
request.post('https://actions.googleapis.com/v2/conversations:send', {
'auth': {
'bearer': tokens.access_token,
},
'json': true,
'body': {
'customPushMessage': notification, 'isInSandbox': true
},
}, (reqErr, httpResponse, body) => {
console.log(httpResponse.statusCode + ': ' + httpResponse.statusMessage);
});
});
I simply can't get this to work with the const userID = conv.arguments.get('UPDATES_USER_ID'); version, because as I said
When I use conv.user.profile.payload.sub as suggested here: https://developers.google.com/actions/identity/user-info the AoG API returns "SendToConversation response: Invalid user id for target."
Is there any way to make this work with Google Sign-In?
Has anyone made this work? I mean with the UPDATES_USER_ID field?
I already created an issue on the samples repo: https://github.com/actions-on-google/dialogflow-updates-nodejs/issues/15 but I was sent here.
Thanks!
While researching why I sometimes got undefined I found an answer on this question that solved my issue.
I've found solution for this problem. While getting UPDATES_USER_ID
conv.arguments.get() only works for first attempt. So, while building
your action you must save it. If you didn't store or save, you can
reset your profile and try again, you will be able to get.
You can reset your user profile for the action here.

alexa skill local could not write to dynamodb

I am writing a node.js skill using ask-sdk and using alexa-skill-local to test the endpoint. I need to persist data to DynamoDb in one of the handler. But I keep getting "missing region error". Please find my code below:
'use strict';
// use 'ask-sdk' if standard SDK module is installed
const Alexa = require('ask-sdk');
const { launchRequestHandler, HelpIntentHandler, CancelAndStopIntentHandler, SessionEndedRequestHandler } = require('./commonHandlers');
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
return handlerInput.responseBuilder
.speak('Sorry, I can\'t understand the command. Please say again.')
.reprompt('Sorry, I can\'t understand the command. Please say again.')
.getResponse();
},
};
////////////////////////////////
// Code for the handlers here //
////////////////////////////////
exports.handler = Alexa.SkillBuilders
.standard()
.addRequestHandlers(
launchRequestHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
ErrorHandler
)
.withTableName('devtable')
.withDynamoDbClient()
.lambda();
And in one of the handler I am trying to get persisted attributes like below:
handlerInput.attributesManager.getPersistentAttributes().then((data) => {
console.log('--- the attributes are ----', data)
})
But I keep getting the following error:
(node:12528) UnhandledPromiseRejectionWarning: AskSdk.DynamoDbPersistenceAdapter Error: Could not read item (amzn1.ask.account.AHJECJ7DTOPSTT25R36BZKKET4TKTCGZ7HJWEJEBWTX6YYTLG5SJVLZH5QH257NFKHXLIG7KREDKWO4D4N36IT6GUHT3PNJ4QPOUE4FHT2OYNXHO6Z77FUGHH3EVAH3I2KG6OAFLV2HSO3VMDQTKNX4OVWBWUGJ7NP3F6JHRLWKF2F6BTWND7GSF7OVQM25YBH5H723VO123ABC) from table (EucerinSkinCareDev): Missing region in config
at Object.createAskSdkError (E:\projects\nodejs-alexa-sdk-v2-eucerin-skincare-dev\node_modules\ask-sdk-dynamodb-persistence-adapter\dist\utils\AskSdkUtils.js:22:17)
at DynamoDbPersistenceAdapter.<anonymous> (E:\projects\nodejs-alexa-sdk-v2-eucerin-skincare-dev\node_modules\ask-sdk-dynamodb-persistence-adapter\dist\attributes\persistence\DynamoDbPersistenceAdapter.js:121:45)
Can we read and write attributes from DynamoDb using alexa-skill-local ? Do we need some different setup to achieve this ?
Thanks
I know that this is a really old topic, but I had the same problem few days ago, and I'm gonna explain how I did it work.
You have to download DynamoDB Locally and follow the instructions from here
Once that you have configure your local DynamoDB and check that it is working. You have to pass it through your code, to DynamoDbPersistenceAdapter constructor.
Your code should look similar to:
var awsSdk = require('aws-sdk');
var myDynamoDB = new awsSdk.DynamoDB({
endpoint: 'http://localhost:8000', // If you change the default url, change it here
accessKeyId: <your-access-key-id>,
secretAccessKey: <your-secret-access-key>,
region: <your-region>,
apiVersion: 'latest'
});
const {DynamoDbPersistenceAdapter} = require('ask-sdk-dynamodb-persistence-adapter');
return new DynamoDbPersistenceAdapter({
tableName: tableName || 'my-table-name',
createTable: true,
dynamoDBClient: myDynamoDB
});
Where <your-acces-key-id>, <your-secrete-access-key> and <your-region> are defined at aws config and credentials files.
The next step is launch your server with alexa-skill-local command as always.
Hope this will be helpfull! =)
Presumably you have an AWS config profile that your skill is using when running locally.
You need to edit the .config file and set the default region (ie us-east-1) there. The region should match the region where your table exists.
Alternatively, if you want to be able to run completely isolated, you may need to write come conditional logic and swap the dynamo client with one targeting an instance of DynamoDB Local running on your machine.

Google OAuth in ASP.NET 5 MVC 6

I'm new to ASP.NET vNext and I don't find how to configure Google OAuth.
I have uncomment the line in Startup.cs:
app.UseGoogleAuthentication();
But where am I supposed to configure it? I tried to replicate the pattern:
services.Configure<MicrosoftAccountAuthenticationOptions>(options =>
{
options.ClientId = Configuration["Authentication:MicrosoftAccount:ClientId"];
options.ClientSecret = Configuration["Authentication:MicrosoftAccount:ClientSecret"];
});
But
services.Configure<GoogleOAuth2AuthenticationOptions>
Isn't recognized even if the dependency is present in project.json:
"Microsoft.AspNet.Authentication.Google": "1.0.0-beta5",
What am I missing?
There is a sample at https://github.com/aspnet/Security/blob/dev/samples/SocialSample/Startup.cs.
I haven't tried it, but it looks like you configure it using app.UseGoogleAuthentication():
app.UseGoogleAuthentication(options =>
{
options.ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com";
options.ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f";
options.Events = new OAuthEvents()
{
OnRemoteError = ctx =>
{
ctx.Response.Redirect("/error?ErrorMessage=" + UrlEncoder.Default.Encode(ctx.Error.Message));
ctx.HandleResponse();
return Task.FromResult(0);
}
};
});
If you're using the configuration store like this
Configuration["Authentication:MicrosoftAccount:ClientId"];
then what you're also missing (if that's what you mean by 'configure Google OAuth') is the part where you store the values in the SecretManager as described in the ASP.NET docs (they use facebook but you can just put whatever keys you want in there). It's a command line tool and it avoids you storing the keys in the code like that. In Google's case you'd probably want to change it to:
Configuration["Authentication:Google:ClientID"];
Configuration["Authentication:Google:ClientSecret"];
but it can be whatever you want.

Extjs 4 - Retrieve data in json format and load a Store. It sends OPTION request

I'm developing an app with Spring MVC and the view in extjs 4. At this point, i have to create a Grid which shows a list of users.
In my Spring MVC controller i have a Get method which returns the list of users in a jsonformat with "items" as a root.
#RequestMapping(method=RequestMethod.GET, value="/getUsers")
public #ResponseBody Users getUsersInJSON(){
Users users = new Users();
users.setItems(userService.getUsers());
return users;
}
If i try to access it with the browser i can see the jsondata correctly.
{"items":[{"username":"name1",".....
But my problem is relative to request of the Ext.data.Store
My Script is the following:
Ext.onReady(function(){
Ext.define('UsersList', {
extend: 'Ext.data.Model',
fields: [
{name:'username', type:'string'},
{name:'firstname', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
storeId: 'users',
model: 'UsersList',
autoLoad: 'true',
proxy: {
type: 'ajax',
url : 'http://localhost:8080/MyApp/getUsers.html',
reader: {type: 'json', root: 'items'}
}
});
Ext.create('Ext.grid.Panel',{
store :store,
id : 'user',
title: 'Users',
columns : [
{header : 'Username', dataIndex : 'username'},
{header : 'Firstname', dataIndex: 'firstname'}
],
height :300,
width: 400,
renderTo:'center'
});
});
When the store tries to retrieve the data and launchs the http request, in my firebug console appears OPTIONS getUsers.html while the request in the browser launchs GET getUsers.html
As a result, Ext.data.Store has not elements and the grid appears with the columnames but without data. Maybe i've missed something
Thank you
You can change the HTTP methods that are used by the proxy for the different CRUD operations using actionMethods.
But, as you can see in the doc (and as should obviously be the case), GET is the default for read operations. So the OPTIONS request you are observing is quite puzzling. Are you sure that there's not another part of your code that overrides the default application-wide? Maybe do a search for 'OPTIONS' in all your project's JS files, to try and find a possible suspect. Apparently there's no match in the whole Ext code, so that probably doesn't come from the framework.
Edit:
Ok, I think I've got it. If your page is not accessed from the same domain (i.e. localhost:8080, the port is taken into account), the XHR object seems to resort to an OPTIONS request.
So, to fix your problem, either omit the domain name completely, using:
url: '/MyApp/getUsers.html'
Or double check that your using the same domain and port to access the page and make the requests.

Getting an open graph action approved - change publish_stream to publish_action

UPDATED CODE:
I have an open graph action pending approval. I received a message back from Facebook saying this:
Your code is currently configured to publish a stream story. You must change your code so that when the test user triggers the action it produces an open graph story. Please make the appropriate changes and resubmit.
I followed all the tutorials regarding publishing actions and my tests all published successfully to my app timeline. The problem is that my app (which is a page tab) is already up and running - so I want to update it and add these new actions.
Are Facebook looking at the code in my current page tab - which is using the fmbl posttofeed share button - or are they looking at the tests I carried out with the new action? Is anyone able to shed some light on this?
This is the code I have in my test page that I used to publish the actions:
function postShare()
{
FB.api(
'/me/namespace:share',
'post',
{ photo: 'https://domain.com' },
function(response) {
if (!response || response.error) {
alert('Error occurred : ' + response.error);
} else {
alert('Share was successful! Action ID: ' + response.id);
}
});
}
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// Init the SDK upon load
window.fbAsyncInit = function() {
FB.init({
appId : 'APP ID', // App ID
channelUrl : '//channel url', // Path to your Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// listen for and handle auth.statusChange events
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.authResponse) {
// user has auth'd your app and is logged into Facebook
FB.api('/me', function(me){
if (me.name) {
document.getElementById('auth-displayname').innerHTML = me.name;
}
})
document.getElementById('auth-loggedout').style.display = 'none';
document.getElementById('auth-loggedin').style.display = 'block';
} else {
// user has not auth'd your app, or is not logged into Facebook
document.getElementById('auth-loggedout').style.display = 'block';
document.getElementById('auth-loggedin').style.display = 'none';
}
});
// respond to clicks on the login and logout links
document.getElementById('auth-loginlink').addEventListener('click', function(){
FB.login();
});
document.getElementById('auth-logoutlink').addEventListener('click', function(){
FB.logout();
});
}
function loginUser() {
FB.login(function(response) { }, {scope:'publish_actions, email'});
}
I can't see how this is configured to publish a stream story and not an open graph story? Can anyone help with this is it's driving me insane and can't find anything out there to suggest what I'm doing is not publishing an action.
If, however when they are reviewing my actions they are looking at the code in my live app then of course it is not set up to trigger any open graph stories - as they haven't been approved yet!
Any help would be hugely appreciated.
Many thanks
Your question isn't entirely clear, but both the publish_actions and publish_stream Permissions both allow you to post Open Graph actions. The publish_stream permission however covers many other publishing types and is also optional, and if users remove that permission you won't be able to post OG actions for those users.
Update your authentication code to request publish_actions instead / as well
Finally got it working. Steps:
1. Added "Publish_action" Permission
2. Tested on FB Graph API Explorer successfully
3. Modified my Javascript (similar code as the postShare() method above)
FB.api('/me/namespace:purchase',
'post',
{ product: 'samples.ogp.me/367683346642550'; },
function(response) {
if (!response || response.error) {
alert('Error occured'+response.error);
} else {
alert('Post was successful! Action ID: ' + response.id);
}
});
The Facebook testers need the actual code running at your production server. They are going to use a Facebook test user to execute all the steps you described when you submitted the action. They won't use the already published stories. They will probably use the "Open Graph Test User".
You have two options here:
Try to publish the action with every user and if it doesn't work, publish the stream (so that the test user get the action published but your real user publish using the old code)
--- OR ---
Identify if the user is a test user (by recording the test users ids) and serve him the new code.
Anyway, the real action flow must be executable on the production server.
Basically you cannot post something to an album or any other kind of post when you are using an open graph story. For example the following is not allowed:
$data = $facebook->api('/me/photos', 'post', $args);//disallowed
$facebook->api(
'me/invig-test:share',
'POST',
array(
'app_id' => $configParam['appId'],
'type' => "test:photo",
'photo' => "http://samples.ogp.me/574859819237737",
'title' => "a photo",
'image[0][url]'=>"http://www.testapp.com/".$imgFile,
'image[0][user_generated]'=>'true',
'message' => $comments,
'fb:explicitly_shared'=>true,
)
);
Instead only do the "share":
$facebook->api(
'me/invig-test:share',
'POST',
array(
'app_id' => $configParam['appId'],
'type' => "test:photo",
'photo' => "http://samples.ogp.me/574859819237737",
'title' => "a photo",
'image[0][url]'=>"http://www.testapp.com/".$imgFile,
'image[0][user_generated]'=>'true',
'message' => $comments,
'fb:explicitly_shared'=>true,
)
);

Resources