Service Dashboard OAuth client invalid scope - cloud-foundry

In my service broker's catalog endpoint, I have defined a dashboard_client like below.
"dashboard_client":{
"id":"test-client-id",
"secret":"test-client-secret",
"redirect_uri":"https://dashboard.cf.myorg.com"
}
In my service dashboard application I am using the client id defined above to initiate the OAuth Authorization Code Grant flow as prescribed in CF Dashboard SSO documentation.
Everything works fine (CF authorization_endpoint redirects to dashboard with auth code and dashboard gets access token from token_endpoint) if the client requests for the minimum scopes cloud_controller_service_permissions.read and openid. e.g.
https://login.cf.myorg.com/oauth/authorize?
response_type=code&
client_id=test-client-id&
scope=openid%20cloud_controller_service_permissions.read&
redirect_uri=https://dashboard.cf.myorg.com/auth
However, if the client requests for additional scopes cloud_controller.read and/or cloud_controller.write (which is also mentioned in the Dashboard SSO documentation), authorization_endpoint redirects to dashboard with an error cloud_controller.read is invalid. Please use a valid scope name in the request.
CF version 2.80.0.
Any idea what is going wrong?

It is this line in UAA which is the show stopper here:
Adding cloud_controller.read,cloud_controller.write to the authorities (must be in authorities and scope) of the client and then updating the service broker via cf update-service-broker should fix that.

Related

Token exchange flow - how to register and login user

Here is my understanding of the token exchange flow:
First i should follow this section of the docs: https://developers.tapkey.io/api/authentication/identity_providers/
After I created identity provider, I want to register my test user using this endpoint https://developers.tapkey.io/openapi/tapkey_access_management_web_api_v1/#/Identity%20Provider%20Users/OwnerIdentityProviderUsers_Put
First question related to the endpoint above is, how do i authorize this request? On swagger documentation there is only clientCredential and AuthorizationCodeAuth options. Does this mean i need one of this types of authorization, so that i can authorize request from my server (from application point of view, lets say).
For endpoints like:
List all owners
Register user
etc.
Now let's say i registered a user, using client credentials to authorize a request.
I am trying to login, following Token Exchange section in docs.
There it says I need to use this POST https://login.tapkey.com/connect/token, i am formatting the jwt as said in the docs, and sending to this endpoint. I am using client_id from my token exchange oAuth client. I got an error with the following message, which is pretty clear to me, but i can't find the solution for it.
{ error: 'unauthorized_client', error_description: 'Client not authorized' }
Mostly, the listet authentication types in the swagger documents are to be able to test the endpoints within the swagger ui. So it is possible to create a oAuth client, pass it to the swagger ui and test the endpoints.
The endpoints itself do not differ between authentication type.
Depending on the purposes the authentication method should be used.
Authorization Code Flow
If you have a service, which works on behalf of a Tapkey user, the authorization code flow should be used.
E.g. you have a booking platform, and your customer should be able to grant access to locks owned by them.
It is not possible to use the authorization code flow to login into the Tapkey Mobile SDK and unlock locks. An authorization client can not request the therefore required scopes.
Client Credential Flow
For server 2 server communication to manage your services, e.g. for adding identity provider users or managing locks which are owned by your services, then the client credential flow would be a good choice.
For that, the client credential client must be authorized as an administrator to the specific locking system.
Token Exchange Flow
To login your users into your app and using the Tapkey Mobile SDK to unlock locks, you have to sign your own JWT tokens on your server and exchange then on the client with the token exchange flow.
Please be aware: It is not possible to use the authorization code flow to sign in as a Tapkey user and then exchange it via token exchange.

AWS VPN using federated login with Google IdP - app_not_configured_for_user

I'm trying to setup a VPN connection using a federated login with Google IdP following these instructions.
Previously, I had configured a saml-provider with Google and it worked fine to authenticate users to the AWS console through Google using ARN roles
WHen I setup the VPN connection, it successfully opens the browser and asks me to select my google account, but after selecting the account I'm getting an error message from Google
According to this help section
Verify that the value in the saml:Issuer tag in the SAMLRequest matches the Entity ID value configured in the SAML Service Provider Details section in the Admin console. This value is case-sensitive.
So this is a problem coming from AWS and not from me ? Is Google IdP compatible at all with VPN authentication ? (I found this doc that mentions compatibility with okta)
Edit
Thanks to some of the answers below, I managed to make it work with Google IdP. Here is a screenshot of relevant SAML Google app screens (note that for groups I ended up adding the employees department, but I guess anything else would have worked)
To be able to save an ACS URL starting with http:// in the G Suite interface, use the trick given by teknowlogist: open the inspector > network tab, perform the request to save an URL with https, then right-click copy it as cURL, replace https by http, paste in regular console, and you're good.
I found a workaround to not being able to input http://127.0.0.1:35001 as the ACS URL on the GSuite SAML app page. The Google admin console only does client-side validation for the https requirement, so you can use the Chrome console to monitor the network call made when modifying the ACS URL.
Then, you can copy this as a curl command and change https to http
#Ted Schroeder —
Previous approach (or, plain Google doesn't work)
I just used a reverse proxy:
mitmproxy \
--listen-port 35000 \
--mode 'reverse:http://127.0.0.1:35001' \
--set keep_host_header=true
If you change Google SAML's ACS URL to be https://127.0.0.1:35000 and click "Test SAML Login", Google will take you to https://127.0.0.1:35000, whose traffic will be redirected to http://127.0.0.1:35001. In the browser I get:
Authentication details received, processing details. You may close this window at any time.
However, using the SAML-tracer extension, I found that there was a URL mismatch (https://127.0.0.1:35000 vs. http://127.0.0.1:35001). Seems like the AWS VPN Client is broadcasting its expected URL as being http://127.0.0.1:35001. So this doesn't seem viable.
Current approach (or, Auth0+Google works)
I tried using Auth0 instead, and got it to work! There's a few hoops — for instance, create a new Auth0 application, go to Addons and enable SAML2 Web App, set Application Callback URL to http://127.0.0.1:35001, and then in Settings use the following:
{
"audience": "urn:amazon:webservices:clientvpn",
"mappings": {
"user_id": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
"email": "NameID",
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"given_name": "FirstName",
"family_name": "LastName",
"upn": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
"groups": "memberOf"
},
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
"signResponse": true
}
Then users, if they download the VPN config from AWS and use the AWS VPN Client app, will be taken to an Auth0 login screen where they can login via Google. Voila! (And then for security, you need to add Auth0 Rules to grant only certain users/groups authorization.)
I don't have a full answer yet, but I have the beginnings of one and I actually got past the 403 error above. The key to all this can be found in the AWS Client VPN information here: https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html
Look for the section entitled "Service provider information for creating an app".
The key is that these are the ACS URL and the Entity ID that need to be used. Unfortunately, G Suite won't let you set the ACS URL to a non-https URL and apparently the AWS Client VPN app won't provide a secure URL for the ACS URL (where the SAML Authenticate response goes).
So, if you set the Entity ID to "urn:amazon:webservices:clientvpn" and have the G Suite SAML app in place according to the instructions, you'll get past the 403. However, since the ACS URL can't be specified you get whatever error message you're likely to get from the ACS URL that the authentication response goes to.
Example scenario
If you set it to https://signon.aws.amazon.com/saml" like you would for AWS Console SSO, you get an error from the AWS sign in that the SAML response was invalid.
And if you set it to https://127.0.0.1:35001 then you get a message from the browser that the "site can't provide a secure connection".
If anybody gets any further with this, I'd love to hear about it. In the meanwhile, I'm going to be looking into non-AWS OpenVPN clients that might actually support G Suite as a SAML IdP.
#alexandergunnarson
Since I don't have the ability to comment (thanks so much for making this easy stackOverflow) I had to edit my answer to get it past the censors.
Unfortunately, we don't have, and probably won't have for some time, G Suite Enterprise because it's too expensive for our startup environment. So OIDP is not a viable option for us now. I figured this would work. Good to know that it does.
I was too having the same issue. In my case, I needed to turn on the two-factor authentication for the account that I was trying to log in with.

Alexa Skill with Azure AD B2C Auth expires after an hour

I am currently building an Alexa skill backed by Azure Functions (.NET Core/C#) and Azure AD B2C for authentication.
For the initial setup, I used mostly used the instructions found in this arcticle. Since, the article was written a couple of years ago, I had to make a few changes. In the end, I landed on the following configuration:
Azure Active Directory B2C
As I mentioned, we are using AAD B2C for authentication. Users of a related application are able to sign-up and sign-in to a React application. The idea is to provide an alternative interface for said users through Alexa intents + utterances.
I created an application for Alexa in AAD B2C with the following settings:
Properties
Web App / Web API: Yes
Allow implicit flow: Yes
Reply URLs: I entered the values provided by the Alexa skill setup (e.g. https://pitangui.amazon.com/api/skil/link/...); there are three different ones. I also added one for my azure function app (this is something that could be incorrect. It was part of what I did while diagnosing other earlier problems); it's in the format: https://myfuncname.azurewebsites.net/.auth/login/aad/callback (Do I even need this???)
App ID URI: https://myorg.onmicrosoft.com/alexa
Include native client: No
Keys
I generated a single App Key, which I'm using as the Secret in the Account Linking section in the Alexa Developer Console.
Many of the examples online mention setting an explicit expiration date here of 1 or 2 years; however, I am not presented with any options at all (i.e. no expiration option), just the code. Could this be part of the problem???
API Access
In the Published scopes section, the Scope's name is user_impersonation. The description is "Access this app on behalf of the signed-in user". The full scope value is: https://myorgsname.onmicrosoft.com/alexa/user_impersonation.
For API Access, I have to API entries here:
One that uses the user_impersonation scope mentioned above.
The second, titled "Access the user's profile", uses:
Acquire an id_token for users (openid)
Acquire a refresh_token for users (offline_access)
AAD B2C User Flow
The user flow that I'm using allows signing up and signing in, it utilizes the following configuration:
Properties
Misc
Enable JavaScript enforcing page layout (preview): On
Token lifetime
Access & ID token lifetimes (minutes): 60
Refresh token lifetime (days): 14
Refresh token sliding window lifetime: "Bounded".
Lifetime length (days): 90
Token compatibility settings
Issuer (iss) claim: https://<domain>/<b2c-tenant-guid>
Subject (sub) claim: ObjectID
Claim representing user flow: tfp
Session behavior
Web app session lifetime (minutes): 1440
Web app session timeout: Rolling
Single sign-on configuration: Tenant
Require ID Token in logout requests: No
Azure Function Authentication Middleware
For the authentication layer within the Azure Function, I'm utilizing the method described in the article mentioned above.
Alexa Developer Console
On the Alexa side of things, I have a really simple skill setup with the following settings:
Endpoint
My endpoint uses the HTTPS option with the default region set to the fully-qualified HTTPS endpoint of my Azure Function App's handler function.
The certificate set to "My development endpoint is a sub-domain of a domain that has a wildcard ..."
Account Linking
The account linking settings are as outlined below:
Do you allow uses to create an account or link to ...: Toggled On
Allow users to enable skill without account linking: Toggled On
Allow users to link their account to your skill from within your application or website: Toggled Off
Auth Code Grant: On
Authorization URI: https://myorg.b2clogin.com/myorg.onmicrosoft.com/oauth2/v2.0/authorize?p=<sign-in-user-flow-policy-name>
Access Token URI: https://myorg.b2clogin.com/myorg.onmicrosoft.com/oauth2/v2.0/token?p=<sign-in-user-flow-policy-name>
Your Client ID: AAD B2C App GUID
Your Secret: Key generated in App settings in AAD B2C for my Alexa Skill App (mentioned in the AAD B2C setup info above).
Your Authentication Scheme: HTTP Basic
Scope: openid and https://myorg.onmicrosoft.com/alexa/user_impersonation
Domain List: login.microsoftonline.com and myorg.b2clogin.com Note: This is probably wrong as I didn't know what to put here. The article above doesn't mention this setting at all
Default Access Token Expiration Time: 3600
Note: The Alexa Redirect URLS at the bottom are what I put in AAD B2C for the Reply URL section.
The Problem
Now for the most important part, The Problem. Everything seems to work at first...I'm able to go to alexa.amazon.com and utilize Link Account (which redirects me to and from my AAD B2C-driven login screen). Once I link accounts, I'm able to successfully utilize an utterance and receive a reply.
The problems starts when I wait an hour (I believe it's an hour). Attempting to initiate the Intent after an hour yields an error on the Azure Function app side of things when it tries to validate the Auth Token.
Can anyone provide me some guidance as to what I may have setup incorrectly or at least some things that I should look into? As I mentioned at the start of this question, many of the references that I'm finding online are out-of-date and do not cover all of the settings that I'm expected to utilize. Many of them are still using microsoftonline.com authority vs. b2clogin.com.
At a glance, I would assume that the problem is that the Alexa skill is failing to refresh its token after it expires after an hour. What do I need to do to ensure that it refreshes correctly?
I think that I have enough information at this point to go ahead and answer my own question. What I found was that the offline_access scope is necessary for Token Refresh to be possible.
Per Microsoft, "The offline_access scope gives your app access to resources on behalf of the user for an extended time. On the consent page, this scope appears as the "Maintain access to data you have given it access to" permission. When a user approves the offline_access scope, your app can receive refresh tokens from the Microsoft identity platform token endpoint. Refresh tokens are long-lived. Your app can get new access tokens as older ones expire.".
You can read more about it here.
To resolve the issue, I ensured that this scope was available in AAD B2C and added it as a referenced scope in the Alexa developer console.
Thanks for giving insight on offline_access. It took few hours to figure out how to implement offline_access. Interestingly offline_access works only with Azure AD, OAuth 1.0 endpoint and not with 2.0.
While trying with 2.0 it kept failing while account linking when multiple scopes were mentioned in Alexa configurations. The scopes I tried were as follows.
https://samplealexabackendapi/
https://graph.microsoft.com/offline_access
Finally I ended up working with OAuth 1.0 endpoint and using the scope https://samplealexabackendapi/.default which considers all scopes available to the app registered.

WSO2 Identity Server - Federated Mode with SAML, Domain Name?

Could you please explain why the WSO2 Travelocity test application requests a "Domain Name" input field in the sign-in screen, when the WSO2 is configured to use, beside basic auth, also a federated authentication mode (WS Release 5.1 - Advanced Configuration). What is the reason to request the domain name part, as for external authentication, for example by use of SAML protocol, I expect to see a redirect onto the external IdP login screen. Apparently the Login redirect is rejected due to this missing input field at the Domain Name. Is there a sample configuration and use case available for setup of outgoing IdP federation?
Further Details from Testings
I've updated the IdP configuration following the WSo2 setting which describes the federation effort with help of Shibboleth products (see below). After this change now I see a login screen from the external IdP ("zee") as well as an interchange of messages between the browser and the external IdP. I also see a SAML POST message in the SSO protocol tracer plugin of the Browser, displaying a long list of claim assertion data, which signals that Login was successfully processed, returning the profile data of my account.
At the Travelocity service provider (SP), now I see the following error message at the screen:
"The entity name must immediately follow the '&' in the entity reference."
I've validated the SAML feedback data and its XML format consistency using an online XML validator, which passed successfully for SAML response XSD format. Such type of XML parser errors are often caused by use of special characters, but its not the case at the current assertions and tests.
The issue happens inside the Travelocity which has difficulties to read the SAML assertion data.
Suggestions from the community how to parse the SAML feedback data using the Travelocity tool, are welcome.
Refer https://docs.wso2.com/display/IS510/Configuring+Single+Sign-On for configuring Basic scenario with travelocity app
To configure federated authenticators:
https://docs.wso2.com/display/IS510/Federated+Authentication
For Advanced Configuration with Multiple Authenticators
https://docs.wso2.com/display/IS510/Configuring+Local+and+Outbound+Authentication+for+a+Service+Provider
Refer https://docs.wso2.com/display/IS510/How+To%3A+Configure+Shibboleth+IdP+as+a+Trusted+Identity+Provider as an example use case.
It seems that you have custom authentication since you have domain name filed at the login prompt.

Bluemix, SSO: Calling REST service from mobile app (public client, native application)

I have a Bluemix web application (Liberty for Java), which implements some web services. These web services should be called from a mobile application (Android). I have now secured this web application by binding it to the Bluemix Single Sign On service (SSO) with a cloud directory created in the SSO service. Using the web app from a web browser works fine; but, I have problems obtaining an access token from the SSO service, which would allow the mobile application to invoke the services.
From the OAuth2 specification (IETF RFC 6749), I figured that the appropriate way of doing this would be the "native application" profile with a "public client" (as specified in Clause 2.1 of the OAuth2 Spec) using the "password" grant type (OAuth2 spec, Clause 4.3 "Resource Owner Password Credentials Grant").
I used the Spring for Android framework for this purpose, and code for this would look like this:
ResourceOwnerPasswordResourceDetails resourceDetails =
new ResourceOwnerPasswordResourceDetails();
resourceDetails.setId("dtu-se2-e15-cloud-directory");
resourceDetails.setAccessTokenUri(APP_SSO_API_ACCESS_TOKEN_URI);
resourceDetails.setClientId(APP_SSO_API_CLIENT_ID);
resourceDetails.setClientSecret(APP_SSO_API_CLIENT_SECRET);
resourceDetails.setGrantType("password");
resourceDetails.setScope(Arrays.asList(SCOPE));
resourceDetails.setUsername(USERNAME);
resourceDetails.setPassword(PASSWORD);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
UserPosition newPosition = restTemplate.postForObject(
POST_POSITION_SERVICE_URI, position, UserPosition.class);
But, I don't think that this code matters, and ultimately made my experiments with obtaining access tokens directly with curl:
Actually, I tried using two different clients with different OAuth2 token endpoints:
I created a client (and client credentials) in the Cloud directory, that I had created in the Bluemix SSO service. And I tried the OAuth2 Token Endpoint URI and the created client credentials. But it appears that this endpoint does not support the grant type "password" at all. It appears that this client is not considered a public client by the endpoint.
I also tried the credentials and OAuth Token Endpoint URI for the Web application itself (which I looked up in the VCAP_SERVICES environment variable). This end point seems to support the grant type "password"; but all variants of requests I could think of, kept responding: invalid_resource_owner_credential.
As I said, I used curl to try out many different variations of requests to these
token endpoints:
used the token endpoint URI of both the SSO services with the web app credentials
as well as the one created in the cloud directory API Access
tried GET and POST (did not make any difference)
tried Content-Type: application/x-www-form-urlencoded and
Content-Type: application/json (both of them seemed to work with the same effect)
providing the client_id only (which always was unsuccessful)
providing the client credentials in the body or parameters, as well as
authenication information in the header (actually, I do not like the idea
of providing the client secret to the Android app, but I tried that too);
as user name, I tried the name as I had created it in the web browser redirection
when registering a new user; but I also tried the user name which the Principal of
the security context of a request would provide (when successfully invoking
a service from a web browser with the user logged in); I even tried the principal's
accessId (non of these worked, I always got: invalid_resource_owner_credential)
used different scopes, and none at all
None of the above (and different combinations of that) would result in a successful
response and an access token for the user. The "best" I could get was a response
invalid_resource_owner_credential (making me believe that at least the client was
accepted in some situations).
Unfortunately, I did not find many things that could be configured concerning client
access (and public clients, in particular), and I did not find much documentation on
which subset of the OAuth2 protocol (grant types and profiles) is supported by the
Bluemix SSO service and the attached cloud directory.
Can anyone could tell me how to authenticate with a Bluemix web application
(Liberty for Java) from a mobile app (Android) as a public client or how to set
up the Bluemix web app and the SSO service to which it is bound so that this is
possible. In case it would matter, I am working with Bluemix in the "US South"
region and under an IBM Academic Initiative membership account for Bluemix.
I would prefer a solution, where the mobile app would not need to know the client
secret, but if this is the only way to make this work for now, adding the client
credentials to the mobile app would be OK.
I would appreciate any help with this problem, thanks in advance,
Ekkart
Bluemix has a mobile-specific service called Mobile Client Access that could help to facilitate security for your mobile app. To read about it, log into Bluemix and look for it under the Mobile category. To ask questions about it here, use or search using the [bluemix-mobile-services] tag.