dexidp / dex

OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
https://dexidp.io
Apache License 2.0
9.36k stars 1.69k forks source link

Need Documentation on how dex works. #1737

Open meenakshi123 opened 4 years ago

meenakshi123 commented 4 years ago

I want to use dex where i need to authenticate user with IAM and my application is not using the standard oauth2 flow.I don't have client id and secret.i need to call a url which returns access token and id token and then i need to redirect that to another page.Is there something like this which i can go through..

zicklag commented 4 years ago

I'm needing to do something very similar or maybe the same as you and I just did some research on how that works. I'll try to reply with an easy to understand/short version when I get the chance, but for now the full spec for OpenID and how to get tokens from dex is here.

Dex is an OpenID Connect provider, and the implicity flow model specifically is perfect for getting tokens from an SPA for example.

meenakshi123 commented 4 years ago

Thanks zicklag for the reply. I already have a url which gives me access token and id token but i am not sure how to use that in dex authentication. Can you please provide more details on it. As it is quite urgent for me.

zicklag commented 4 years ago

I'm not sure I fully understand your setup.

Do you:

  1. Have Dex setup so that it uses some external service to authenticate users such as GitHub and you want to allow users to log into your app using the Dex login form, or
  2. You want to have Dex use your application as an authentication backend?
meenakshi123 commented 4 years ago

I want to use dex for authentication.But i am not sure how to use it in my case..in my case i have only a url which gives me access token and id token and redirect me to callback api with these tokens..using id token i can get user identity but it does not redirect me automatically to application dashboard page..I have done same thing with ldap..which was fine..as we have ldap connector in dex. But not sure about IAM as we don't have any connector.May be we need to customize it.

zicklag commented 4 years ago

What is IAM?

meenakshi123 commented 4 years ago

identity and access mgmt

meenakshi123 commented 4 years ago

may i know what you are trying to achieve.May be i can try to relate.Have you worked with dex earlier?

zicklag commented 4 years ago

I've just finished setting up Dex to point to an LDAP auth backend and successfully gotten the id_token from Dex in my application. The workflow is like this

  1. Use hits my application ( they are unauthorized )
  2. My app uses node-openid-client to discover the redirect URL for dex:

    let issuer = await Issuer.discover(
    "http://123.456.789.100:5556/.well-known/openid-configuration"
    );
    
    const client = new issuer.Client({
    client_id: "testapp",
    client_secret: "password",
    // This redirect URI must point to the application URL that you want Dex to redirect to after
    // the user is authenticated.
    redirect_uris: ["http://123.456.789.100:3002/callback"],
    response_types: ["id_token"]
    });
    
    // My app will redirect to this URL to get the user authenticated
    const url = client.authorizationUrl({
    scope: "openid groups profile email",
    nonce: "hellononce",
    response_mode: "query",
    display: "popup"
    });
  3. My app redirect's the user to Dex
  4. Dex authenticates the user and redirects back to my app using the URL in the redirect_uris section in the above code sample. Dex will redirect to that URL with the tokens in the hastag: http://123.456.789.100:3002/callback#id_token=[token]&access_token=[other_token].
  5. My SPA app reads the tokens out of the hashtag and uses the id_token to make requests to my backend API

Is this similar to what you are trying to accomplish?

meenakshi123 commented 4 years ago

in my case i don't have client id and secret. will it work if i don't pass it?or can it be some random text?

zicklag commented 4 years ago

Ah, you set the client id and secret in the dex config yaml in the staticClients section:

staticClients:
  - id: my-client-id
    redirectURIs:
      - http://123.456.789.100:3002/callback
    name: My Client ID
    secret: my-client-secret

You can set those to whatever you want, but you have to set them.

meenakshi123 commented 4 years ago

ok..I will try this..And is your code similar to other connectors?Do you have Open,LoginURL,HAndleCallback this method in ur connector?can you show in network tab, wnt to see the flow.

zicklag commented 4 years ago

I don't know what you mean exactly...

I haven't seen any other connector's code yet. In my use-case everything happens in the JavaScript frontend ( or it will once I've got it all put together ).

The JavaScript frontend will check a cookie for the id_token, and if it doesn't find it it will use the above code to calculate the Dex redirect URL, then it will set the web-page's href to that URL so Dex can authenticate the user. When dex redirect's back to the app, the JavaScript frontend will read the id_token from the hashtag and use Axios to make API requests with the token in the Authorization header.

So in that case all the steps such as redirecting and handling the callback are done in the JavaScript frontend.

meenakshi123 commented 4 years ago

I see..i think the node-openid-client approach is little bit different than the dex connector flow.If you want we can connect on hangout and can explain you better, if you don't mind.It is quite urgent for me.

Can you explain this part from ur application; My app redirect's the user to Dex Dex authenticates the user and redirects back to my app using the URL in the redirect_uris section in the above code sample.

zicklag commented 4 years ago

Sorry, because of network restrictions on my side hangouts doesn't work for me. Unfortunately this is the best place to discuss that I have access to.

zicklag commented 4 years ago

Not sure if this helps, but here is a sequence diagram:

Untitled Diagram

zicklag commented 4 years ago

If you have a specific step you have questions about then I can try to explain it better.

Also, are you doing this from a single paged application ( SPA )? Or are you doing it from something like a PHP web application or something similar. I might be able to publish an example repo that shows how I'm doing it or how you could do it depending on what application stack you are using.

meenakshi123 commented 4 years ago

No Issues..I am interested in step 4 and step 5. It's a application but completely in go. and we are integrating it with kubeflow.I am new in golang and dex. If you see other connectors, may be you can get idea what i am talking about. Let me explain you more what i have tried. I have created a new connector similer to other connectors. but i have to add a new step where user can call a api(defined by me) and in response it redirects me to callback url with access token and id token.From callback url, i want to redirect to my application page but this is not happening.because i think dex authentication is not happening.

zicklag commented 4 years ago

OK, so those are completely handled by Dex. After step 2, the user is presented with the Dex login screen:

image

In my case I select LDAP and then I login with my username and password there:

image


Have you been able to get to that point so far?

meenakshi123 commented 4 years ago

yes

zicklag commented 4 years ago

OK, so what happens when you submit the login form?

It should redirect back to your application, with the id_token ( and other stuff ) in the URL.

meenakshi123 commented 4 years ago

This is my 1st request- Request URL: http://127.0.0.1:5556/dex/auth/idam?req=bfql54ekleejpfhpjk4uqxfb4 2nd request: http://127.0.0.1:5556/dex/auth/?client_id=&response_type=code&state=bfql54ekleejpfhpjk4uqxfb4 I think it is taking from example-app.In my dex-config.yaml, i have provided this:-oauth2: response_types: ["id_token"]

but i want to know where should i add my api call which returns me accestoken.

zicklag commented 4 years ago

So that first request is wrong I think. And you shouldn't need to make a separate second request.

Here's a walk-though you should be able to follow along with:

First, here is the Dex complete dex config yaml. Start dex up with this yaml. For now we just use a local password provider, but you can connect LDAP or whatever and it will work the same.

issuer: http://127.0.0.1:5556/dex

storage:
  type: sqlite3
  config:
    file: ":memory:"

web:
  http: 0.0.0.0:5556

logger:
  level: "debug"
  format: "text"

oauth2:
  responseTypes: ["id_token"]

staticClients:
  - id: my-application
    redirectURIs:
      - http://127.0.0.1:3000/callback
    name: My Application
    secret: password

enablePasswordDB: true

staticPasswords:
  - email: "dude@example.com"
    # bcrypt hash of the string "password"
    hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
    username: "dude"
    userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"

Once Dex is running, put this URL in your browser window:

127.0.0.1:5556/dex/auth?client_id=my-application&scope=openid%20groups%20profile%20email&response_type=id_token&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Fcallback&nonce=hellononce

To break it down the URL has these components in the query string:

This will present you with the login form. Use these credentials:

Email: dude@example.com Password: password

Once you submit it will ask you to grant access. Once you grant access the browser will redirect to a new URL ( If you don't have anything on your computer listening on port 3000 it will display a connect error, but that is fine for the sake of this demonstration ). You can copy that URL and paste it into something to inspect it:

http://127.0.0.1:3000/callback#access_token=[access_token]&expires_in=86399&id_token=[id_token]&state=&token_type=bearer

This is the information you need in your App. The ID token is in this URL's hashtag. This only works if your App is an SPA or otherwise has some JavaScript in the frontend to analyze the hashtag. If you do not have an SPA or a JavaScript in your frontend you will need to use a different flow, which I can also explain.

zicklag commented 4 years ago

To clarify, you don't need to use node-openid-cient at all. That just automates putting together the first request and helping with the workflow a bit, but it is easier to learn about how it works without involving it.

meenakshi123 commented 4 years ago

This is fine.but in my case, we have one extra thing- to call a api and i am getting tokens from there and because of that i am confused. and even i don't have username password too.I h.ave a singal button when i click on that, it should call my api in that api it checks the computer certificated and based on that it returns id token and access token.Now the point is, using that token , dex authentication is not happening.

zicklag commented 4 years ago

So you have an API that will figure out whether or not a user is authenticated, and you want Dex to use that API to authenticate users? For example:

In that case you would have to write you own connector for Dex, which would require writing some Go and getting it merged into Dex. Or you could fork Dex for your own use and add the code in your fork. I don't know what it takes to implement a Dex connector, but you can see the list of built-in connectors here.

meenakshi123 commented 4 years ago

Right..I have created a new connector but i am little bit confused about the connector methods(Open,LoginURL, Callback).I am not sure how this works and what each method will do in my case.and these methods are required.

zicklag commented 4 years ago

Ah, OK, that makes more sense. I thought I was misunderstanding something.

When it comes to that, I unfortunately don't know much. :confused: I haven't implemented my own connector in Dex yet, nor have I written much Go.

meenakshi123 commented 4 years ago

same case with me..If you find out any documentation about these methods or any blogs which are related to this.Please ping me.Thanks for your time and help.

zicklag commented 4 years ago

:+1: No problem. :)