Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .schemastore/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@
},
"provider": {
"title": "Provider",
"description": "Can be one of github, github-app, gitlab, generic, google, microsoft, discord, salesforce, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon.",
"description": "Can be one of github, github-app, gitlab, generic, google, microsoft, discord, salesforce, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon, okta.",
"type": "string",
"enum": [
"github",
Expand All @@ -456,7 +456,8 @@
"linkedin",
"linkedin_v2",
"lark",
"x"
"x",
"okta"
],
"examples": ["google"]
},
Expand Down
5 changes: 3 additions & 2 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@
},
"provider": {
"title": "Provider",
"description": "Can be one of github, github-app, gitlab, generic, google, microsoft, discord, salesforce, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon.",
"description": "Can be one of github, github-app, gitlab, generic, google, microsoft, discord, salesforce, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon, okta.",
"type": "string",
"enum": [
"github",
Expand All @@ -462,7 +462,8 @@
"linkedin_v2",
"lark",
"x",
"fedcm-test"
"fedcm-test",
"okta"
],
"examples": ["google"]
},
Expand Down
2 changes: 2 additions & 0 deletions selfservice/strategy/oidc/provider_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Configuration struct {
// - dingtalk
// - linkedin
// - patreon
// - okta
Provider string `json:"provider"`

// Label represents an optional label which can be used in the UI generation.
Expand Down Expand Up @@ -189,6 +190,7 @@ var supportedProviders = map[string]func(config *Configuration, reg Dependencies
"line": NewProviderLineV21,
"jackson": NewProviderJackson,
"fedcm-test": NewProviderTestFedcm,
"okta": NewProviderOkta,
}

func (c ConfigurationCollection) Provider(id string, reg Dependencies) (Provider, error) {
Expand Down
10 changes: 10 additions & 0 deletions selfservice/strategy/oidc/provider_microsoft.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var _ OAuth2Provider = (*ProviderMicrosoft)(nil)

type ProviderMicrosoft struct {
*ProviderGenericOIDC
JWKSUrl string
}

func NewProviderMicrosoft(
Expand All @@ -35,6 +36,7 @@ func NewProviderMicrosoft(
config: config,
reg: reg,
},
JWKSUrl: "https://login.microsoftonline.com/" + config.Tenant + "/discovery/v2.0/keys",
}
}

Expand Down Expand Up @@ -130,3 +132,11 @@ type microsoftUnverifiedClaims struct {
func (c *microsoftUnverifiedClaims) Valid() error {
return nil
}

var _ IDTokenVerifier = new(ProviderMicrosoft)

func (p *ProviderMicrosoft) Verify(ctx context.Context, rawIDToken string) (*Claims, error) {
keySet := gooidc.NewRemoteKeySet(ctx, p.JWKSUrl)
ctx = gooidc.ClientContext(ctx, p.reg.HTTPClient(ctx).HTTPClient)
return verifyToken(ctx, keySet, p.config, rawIDToken, p.config.IssuerURL)
}
76 changes: 76 additions & 0 deletions selfservice/strategy/oidc/provider_okta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package oidc

import (
"context"

gooidc "github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"

"github.com/ory/x/stringslice"
)

type ProviderOkta struct {
*ProviderGenericOIDC
JWKSUrl string
}

func NewProviderOkta(
config *Configuration,
reg Dependencies,
) Provider {
return &ProviderOkta{
ProviderGenericOIDC: &ProviderGenericOIDC{
config: config,
reg: reg,
},
JWKSUrl: config.IssuerURL + "/oauth2/v1/keys",
}
}

func (o *ProviderOkta) oauth2ConfigFromEndpoint(ctx context.Context, endpoint oauth2.Endpoint) *oauth2.Config {
scope := o.config.Scope
if !stringslice.Has(scope, gooidc.ScopeOpenID) {
scope = append(scope, gooidc.ScopeOpenID)
}

return &oauth2.Config{
ClientID: o.config.ClientID,
ClientSecret: o.config.ClientSecret,
Endpoint: endpoint,
Scopes: scope,
RedirectURL: o.config.Redir(o.reg.Config().OIDCRedirectURIBase(ctx)),
}
}

func (o *ProviderOkta) OAuth2(ctx context.Context) (*oauth2.Config, error) {
p, err := o.provider(ctx)
if err != nil {
return nil, err
}

endpoint := p.Endpoint()
return o.oauth2ConfigFromEndpoint(ctx, endpoint), nil
}

func (o *ProviderOkta) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
options := o.ProviderGenericOIDC.AuthCodeURLOptions(r)
return options
}

var _ IDTokenVerifier = new(ProviderOkta)

func (p *ProviderOkta) Verify(ctx context.Context, rawIDToken string) (*Claims, error) {
keySet := gooidc.NewRemoteKeySet(ctx, p.JWKSUrl)
ctx = gooidc.ClientContext(ctx, p.reg.HTTPClient(ctx).HTTPClient)
return verifyToken(ctx, keySet, p.config, rawIDToken, p.config.IssuerURL)
}

var _ NonceValidationSkipper = new(ProviderOkta)

func (a *ProviderOkta) CanSkipNonce(c *Claims) bool {
// Not all SDKs support nonce validation, so we skip it if no nonce is present in the claims of the ID Token.
return c.Nonce == ""
}
35 changes: 35 additions & 0 deletions selfservice/strategy/oidc/provider_okta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package oidc_test

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ory/kratos/internal"
"github.com/ory/kratos/selfservice/strategy/oidc"
)

func TestProviderWorkOS(t *testing.T) {
_, reg := internal.NewVeryFastRegistryWithoutDB(t)

p := oidc.NewProviderOkta(&oidc.Configuration{
Provider: "okta",
ID: "test-okta-id",
ClientID: "test-client-id",
ClientSecret: "test-client-secret",
IssuerURL: "https://foo.okta.com",
Mapper: "file://./stub/oidc.facebook.jsonnet",
RequestedClaims: nil,
Scope: []string{},
}, reg)

c, err := p.(oidc.OAuth2Provider).OAuth2(context.Background())
require.NoError(t, err)
assert.Equal(t, "https://foo.okta.com/oauth2/v1/token", c.Endpoint.TokenURL)
assert.Equal(t, "https://foo.okta.com/oauth2/v1/authorize", c.Endpoint.AuthURL)
}
Loading