-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Have Hydra store usernames linked to tokens #364
Comments
Here is the code used to create tokens (for demonstration purposes and since it seems like other people had asked similar questions): package client
import (
"net/http"
ldap "github.com/jtblin/go-ldap-client"
"github.com/michael-golfi/log4go"
hydra "github.com/ory-am/hydra/sdk"
"github.com/spf13/viper"
"fmt"
"context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/clientcredentials"
)
// ClientCredentials uses the OAuth configuration to request access tokens from the OAuth Server
// The server will assume an SSL connection
func ClientCredentials(c *clientcredentials.Config, hydraClient *hydra.Client) func(rw http.ResponseWriter, r *http.Request) {
bindDn := viper.GetString("ldap.bind")
bindPassword := viper.GetString("ldap.password")
baseDn := viper.GetString("ldap.base")
host := viper.GetString("ldap.host")
port := viper.GetInt("ldap.port")
log4go.Info("Connecting to LDAP Server: ldaps://%s:%d\nWith \tbind: %s\n\tbase: %s", host, port, bindDn, baseDn)
ldapClient := &ldap.LDAPClient{
Base: baseDn,
Host: host,
Port: port,
UseSSL: true,
InsecureSkipVerify: true,
BindDN: bindDn,
BindPassword: bindPassword,
UserFilter: "(&(cn=%s)(objectClass=User)(!(objectCategory=Computer)))",
GroupFilter: "(memberUid=%s)",
Attributes: []string{},
}
return func(w http.ResponseWriter, r *http.Request) {
log4go.Info("Authenticate")
r.ParseForm()
username := r.FormValue("username")
password := r.FormValue("password")
if username == "" || password == "" {
log4go.Error("No username or password provided")
w.WriteHeader(401)
return
}
ok, _, err := ldapClient.Authenticate(username, password)
if err != nil {
log4go.Error("Error authenticating user %s: %+v", username, err)
w.WriteHeader(500)
return
}
if !ok {
log4go.Error("Authentication failed for user %s", username)
w.WriteHeader(401)
return
}
defer ldapClient.Close()
accessToken, err := c.Token(context.Background())
if err != nil {
w.WriteHeader(500)
log4go.Error("Couldn't get a token: %s", err.Error())
return
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(translateToken(accessToken)))
}
}
func translateToken(tok *oauth2.Token) string {
return fmt.Sprintf(`{"token_type":"%s","expires_in":"%s","access_token":"%s"}`,
tok.TokenType,
tok.Expiry,
tok.AccessToken)
} |
This isn't true. The subject (user, app, server) that authorized the token is displayed by the |
The Client
|
Sorry I didn't mean to be rude, I'm more confused than anything. I was hoping you might be able to clear up some of that... Been banging my head against the wall for a little while now :/. When performing client credentials the sub is the same as the client id right? So maybe I'm more confused about the flows themselves. If I use authorization code flow then can I get the username as the subject? |
Oh, I misunderstood you then. I think you're confused about the OAuth2 flows, I highly recommend reading: https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2 TL;DR the client_credential flow does not involve a user. The flow is intended for programmatic APIs that require an access token. If you're looking for getting a token on behalf of a user, use the implicit or authorize_code flows |
Ok thank you so much. I'm going to close for now. I will also provide some code for others if they end up in a similar situation once I'm done this! |
You're welcome. Always happy to be of help :) |
As I understand, OpenID Connect is supposed to be the authentication-side for OAuth (so to speak). Right now I have token creation using client credentials with a backend (called Gatekeeper for all intents and purposes) acting as an intermediary between a webapp and Hydra. But there is no linking of usernames to tokens in Hydra so when introspection is done with Hydra, there is no concept of which user the token was requested for. Which means that I would need to start caching in Gatekeeper. This wouldn't be ideal because I want it to be stateless and to keep the majority of auth logic in Hydra.
I know that client credentials demands that the client id and subject are equal, does Hydra have any way to cache the username of the requesting user (given that the username is provided)?
The text was updated successfully, but these errors were encountered: