GithubHelp home page GithubHelp logo

keycloak's Introduction

keycloak

ci codeql Go Reference Go Report Card Total alerts

keycloak is a Go client library for accessing the Keycloak API.

Installation

go get github.com/zemirco/keycloak/v2

Usage

package main

import (
    "context"

    "github.com/zemirco/keycloak/v2"
    "golang.org/x/oauth2"
)

func main() {
    // create your oauth configuration
    config := oauth2.Config{
        ClientID: "admin-cli",
        Endpoint: oauth2.Endpoint{
            TokenURL: "http://localhost:8080/realms/master/protocol/openid-connect/token",
        },
    }

    // get a valid token from keycloak
    ctx := context.Background()
    token, err := config.PasswordCredentialsToken(ctx, "admin", "admin")
    if err != nil {
        panic(err)
    }

    // create a new http client that uses the token on every request
    client := config.Client(ctx, token)

    // create a new keycloak instance and provide the http client
    k, err := keycloak.NewKeycloak(client, "http://localhost:8080/")
    if err != nil {
        panic(err)
    }

    // start using the library and, for example, create a new realm
    realm := &keycloak.Realm{
        Enabled: keycloak.Bool(true),
        ID:      keycloak.String("myrealm"),
        Realm:   keycloak.String("myrealm"),
    }

    res, err := k.Realms.Create(ctx, realm)
    if err != nil {
        panic(err)
    }
}

Examples

Development

Use docker-compose to start Keycloak locally.

docker-compose up -d

Keycloak is running at http://localhost:8080/. The admin credentials are admin (username) and admin (password). If you want to change them simply edit the docker-compose.yml.

Keycloak uses PostgreSQL and all data is kept across restarts.

Use down if you want to stop the Keycloak server.

docker-compose down

Architecture

The main entry point is keycloak.go. This is where the Keycloak instance is created. It all starts in this file.

Within Keycloak we also have the concept of clients. They are the ones that connect to Keycloak for authentication and authorization purposes, e.g. our frontend and backend apps. That is why this library simply uses the keycloak instance of type Keycloak and not a client instance like go-github. Although technically this library is a Keycloak client library for Go. However this distinction should make it clear what is meant when we talk about a client in our context.

Testing

You need to have Keycloak running on your local machine to execute the tests. Simply use docker-compose to start it.

All tests are independent from each other. Before each test we create a realm and after each test we delete it. You don't have to worry about it since the helper function createRealm does that automatically for you. Inside this realm you can do whatever you want. You don't have to clean up after yourself since everything is deleted automatically when the realm is deleted.

Run all tests.

go test -race -v ./...

Create code coverage.

go test -v ./... -coverprofile=coverage.out
go tool cover -html=coverage.out -o coverage.html

We have also provided a simple Makefile that run both jobs automatically.

make

Open coverage.html with your browser.

Design goals

  1. Zero dependencies

    It's just the Go standard library.

    The only exception is go-querystring to easily handle query parameters.

  2. Idiomatic Go

    Modelled after go-github and go-jira.

  3. Keep authentication outside this library

    This is the major difference to most of the other Go Keycloak libraries.

    We leverage the brilliant oauth2 package to deal with authentication. We have provided multiple examples to show you the workflow. It basically means we do not provide any methods to call the /token endpoint.

  4. Return struct and HTTP response

    Whenever the Keycloak API returns JSON content you'll get a proper struct as well as the HTTP response.

    func (s *ClientsService) Get(ctx context.Context, realm, id string) (*Client, *http.Response, error)

Related work

License

MIT

keycloak's People

Contributors

dmartinol avatar drpsychick avatar keloran avatar zemirco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

keycloak's Issues

http client is not auto relogin after refresh_token expired.

config := oauth2.Config{
	ClientID:     enums.Env.KeycloakClientId,
	ClientSecret: enums.Env.KeycloakClientSecret,
	RedirectURL:  enums.Env.KeycloakRedirect,
	Endpoint: oauth2.Endpoint{
		TokenURL: fmt.Sprintf("%srealms/%s/protocol/openid-connect/token", enums.Env.KeycloakEndpoint, enums.Env.KeycloakRealm),
	},
}

// get a valid token from keycloak
ctx := context.Background()
token, err := config.PasswordCredentialsToken(ctx, enums.Env.KeycloakAdmin, enums.Env.KeycloakPassword)
if err != nil {
	panic(err)
}

// create a new http client that uses the token on every request
client := config.Client(ctx, token)

// create a new keycloak instance and provide the http client
clientKeycloak, err := keycloak.NewKeycloak(client, enums.Env.KeycloakEndpoint)

clientKeycloak can't call api after refresh_token expired.

Missing service to add role to a Group

GroupsService is missing the API to manage the roles mapped to a given group.
At least these two methods should be added:
func (s *GroupsService) AddRealmRoles(ctx context.Context, realm, group *Group, roles []*Role) (*http.Response, error)
func (s *GroupsService) RemoveRealmRoles(ctx context.Context, realm, group *Group, roles []*Role) (*http.Response, error)

Get PasswordCredentialsToken with TOTP

First of all this is a very great project.

In order to get a valid token you have to pass in username and admin like the following code snippet

// get a valid token from keycloak
    ctx := context.Background()
    token, err := config.PasswordCredentialsToken(ctx, "admin", "admin")
    if err != nil {
        panic(err)
    }

Unfortunately, I can't pass a required OTP-Token, so that my two factor authentication works. Can I adjust the PasswordCredentialsToken or add a second method, that I am able to pass the OTP-Token? The following code snippet describes my idea in detail

// get a valid token from keycloak
    ctx := context.Background()
    token, err := config.PasswordCredentialsToken(ctx, "admin", "admin", "123456")
    if err != nil {
        panic(err)
    }

The result would be another line totp=<one time token> within the application/x-www-form-urlencoded body

Create attribute to user

Hi,

How do I create attributes from the user

	user := &keycloak.User{
		Enabled:   keycloak.Bool(true),
		Username:  keycloak.String(data.FullName),
		Email:     keycloak.String(data.Email),
		FirstName: keycloak.String(data.FirstName),
		LastName:  keycloak.String(data.LastName),
		Attributes: ???
	}

I include this block but not working

	user := &keycloak.User{
		Enabled:   keycloak.Bool(true),
		Username:  keycloak.String(data.FullName),
		Email:     keycloak.String(data.Email),
		FirstName: keycloak.String(data.FirstName),
		LastName:  keycloak.String(data.LastName),
		Attributes: {"attribute01": "value01","attribute02": "value02" }
	}

What is the correct format to create attributes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.