cf-java-client icon indicating copy to clipboard operation
cf-java-client copied to clipboard

how to Use SSO feature with Java client ?

Open parasuram-tanguturu opened this issue 6 years ago • 5 comments

hi, how to use java client to execute following command programatically. cf login -a "api of cf" -sso

parasuram-tanguturu avatar Sep 18 '18 20:09 parasuram-tanguturu

I believe this call, implemented here, is what you're looking for.

twoseat avatar Sep 19 '18 09:09 twoseat

how to get onetime passcode programatically using cf-java-client

parasuram-tanguturu avatar Sep 20 '18 10:09 parasuram-tanguturu

That endpoint hasn't yet been implemented. I'll add it as a todo, but it's going to be a low priority - it's a surprisingly complicated thing to implement, for a relatively minor feature.

twoseat avatar Sep 21 '18 14:09 twoseat

Has there been any progress made here?

I have an app https://github.com/pacphi/cf-butler that leverages some config to drive which tokenProvider implementation gets instantiated in lines 32-47 here: https://github.com/pacphi/cf-butler/blob/master/src/main/java/io/pivotal/cfapp/config/ButlerConfig.java.

When deploying this app to Cloud Foundry I first cf login -a {api_endpoint} -sso and capture the passcode. Then I use the passcode as an environment variable defined in a secrets.json file consumed as configuration by either a cups or credhub service instance bound to my app; then I start the app. The sequence of cf-cli commands I used looks like this:

cf target -o {org} -s {space}
cf push --no-start
cf set-env cf-butler SPRING_PROFILES_ACTIVE 'test,cloud,secrets'
cf create-service credhub default cf-butler-secrets -c secrets.json
cf bind-service cf-butler cf-butler-secrets
cf start cf-butler

the aforementioned secrets.json file looks something like

{
	"TOKEN_PROVIDER": "sso",
	"CF_API-HOST": "api.run.pcfone.io",
	"CF_PASSCODE": "Mw6DiVwwJl",
	"CF_ORGANIZATION-BLACK-LIST": [ "system" ],
	"CRON_COLLECTION": "0 0 0 * * *",
	"CRON_EXECUTION": "0 0 2 * * *"
}

This still doesn't work as I'd expect. When I consult the logs I see

2019-01-27T08:09:16.54-0800 [APP/PROC/WEB/0] OUT 2019-01-27 16:09:16.540 DEBUG 16 --- [ry-client-nio-5] r.ipc.netty.channel.ChannelOperations    : [id: 0xaca1a83c, L:/10.255.25.52:55764 - R:api.run.pcfone.io/10.193.36.220:443] [HttpClient] Handler is being applied: HttpClientHandler{startURI=https://api.run.pcfone.io:443/v2/organizations?page=1, method=GET, handler=reactor.ipc.netty.http.client.HttpClient$$Lambda$451/0x00000001005c6840@1e05025c}
   2019-01-27T08:09:16.54-0800 [APP/PROC/WEB/0] OUT 2019-01-27 16:09:16.539 DEBUG 16 --- [ry-client-nio-8] r.i.n.http.client.HttpClientOperations   : [id: 0xcbb8b951, L:/10.255.25.52:55762 - R:api.run.pcfone.io/10.193.36.220:443] Outbound error happened
   2019-01-27T08:09:16.54-0800 [APP/PROC/WEB/0] OUT org.cloudfoundry.uaa.UaaException: unauthorized: Invalid passcode

Now what's interesting is if I...

  1. authenticate via sso and capture the passcode

  2. author an application-pcfone.yml to contain (for example)

cf:
  apiHost: api.run.pcfone.io
  passcode: Mw6DiVwwJl
  organizationBlackList:
    - system

token:
  provider: sso

spring:
  profiles.include: jdbc

logging:
  level:
    org.springframework: INFO
    org.cloudfoundry.reactor: DEBUG

# Set schedule for this task to adhere to
# @see https://crontab.guru for help, first parameter is seconds
cron:
  collection: "0 0 0 * * *"
  execution: "0 0 2 * * *"

management:
  endpoints:
    web:
      exposure:
        include: env,bean,info,health,metrics,scheduledtasks,loggers,logfile

---
spring:
  profiles: jdbc

  datasource:
    driver-class-name: org.hsqldb.jdbc.JDBCDriver
    url: jdbc:hsqldb:mem:cf-butler
    username: sa
    password: 

Note the cf.passcode sets the passcode for use by the tokenProvider.

Also take note of the base configuration here: https://github.com/pacphi/cf-butler/blob/master/src/main/resources/application.yml.

  1. start this app up on my local workstation with
gradle bootRun -Dspring.profiles.active=pcfone

the app successfully authenticates and functions as desired. It's only when I deploy to Cloud Foundry that it fails.

Help?

pacphi avatar Jan 27 '19 16:01 pacphi

So I figured this out on my own. See this commit

https://github.com/pacphi/cf-butler/commit/61745afd7f7796af76ac6f4854a68cf8cb31fba8

to see what I did.

TL;DR

Update token provider implementation to RefreshTokenGrantTokenProvider. Obtain value for cf.refreshToken from ~/.cf/config.json after you cf login -a {api_endpoint} -sso. That value is from "RefreshToken" key within that file.

pacphi avatar Jan 27 '19 19:01 pacphi