Skip to content
Snippets Groups Projects
Commit b450ee8a authored by Rohith's avatar Rohith
Browse files

- changing the name of the field from rolesallowed to roles

parent 50e8b041
No related branches found
No related tags found
No related merge requests found
...@@ -134,9 +134,28 @@ resources: ...@@ -134,9 +134,28 @@ resources:
- url: /admin - url: /admin
methods: methods:
- GET - GET
roles_allowed: roles:
- <CLIENT_APP_NAME>:<ROLE_NAME> - client:test1
- <CLIENT_APP_NAME>:<ROLE_NAME> - client:test2
- url: /backend
roles:
- client:test1
```
Note, anything defined in the configuration file can also be configured as command line options, so the above would be reflected as;
```shell
bin/keycloak-proxy \
--discovery-url=https://keycloak.example.com/auth/realms/<REALM_NAME> \
--client-id=<CLIENT_ID> \
--secret=<SECRET> \
--listen=127.0.0.1:3000 \
--redirection-url=http://127.0.0.3000 \
--refresh-sessions=true \
--encryption-key=AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j \
--upstream=http://127.0.0.1:80 \
--resource="uri=/admin|methods=GET|roles=test1,test2" \
--resource="uri=/backend|roles=test1"
``` ```
#### **Upstream Headers** #### **Upstream Headers**
...@@ -194,7 +213,7 @@ fix this by fixing up the paths, you can add excepts to the protected resources. ...@@ -194,7 +213,7 @@ fix this by fixing up the paths, you can add excepts to the protected resources.
- url: / - url: /
methods: methods:
- GET - GET
roles_allowed: roles:
- <CLIENT_APP_NAME>:<ROLE_NAME> - <CLIENT_APP_NAME>:<ROLE_NAME>
- <CLIENT_APP_NAME>:<ROLE_NAME> - <CLIENT_APP_NAME>:<ROLE_NAME>
``` ```
...@@ -204,6 +223,7 @@ Or on the command line ...@@ -204,6 +223,7 @@ Or on the command line
```shell ```shell
--resource "uri=/some_white_listed_url,white-listed=true" --resource "uri=/some_white_listed_url,white-listed=true"
--resource "uri=/" # requires authentication on the rest --resource "uri=/" # requires authentication on the rest
--resource "uri=/admin|roles=admin,superuser|methods=POST,DELETE
``` ```
#### **Mutual TLS** #### **Mutual TLS**
......
...@@ -82,13 +82,13 @@ func (r *Config) isValid() error { ...@@ -82,13 +82,13 @@ func (r *Config) isValid() error {
if strings.HasSuffix(r.RedirectionURL, "/") { if strings.HasSuffix(r.RedirectionURL, "/") {
r.RedirectionURL = strings.TrimSuffix(r.RedirectionURL, "/") r.RedirectionURL = strings.TrimSuffix(r.RedirectionURL, "/")
} }
if r.EncryptionKey == "" && r.RefreshSession { if r.EncryptionKey == "" && r.RefreshSessions {
return fmt.Errorf("you have not specified a encryption key for encoding the session state") return fmt.Errorf("you have not specified a encryption key for encoding the session state")
} }
if r.EncryptionKey != "" && len(r.EncryptionKey) < 32 { if r.EncryptionKey != "" && len(r.EncryptionKey) < 32 {
return fmt.Errorf("the encryption key is too short, must be longer than 32 characters") return fmt.Errorf("the encryption key is too short, must be longer than 32 characters")
} }
if r.MaxSession == 0 && r.RefreshSession { if r.MaxSession == 0 && r.RefreshSessions {
r.MaxSession = time.Duration(6) * time.Hour r.MaxSession = time.Duration(6) * time.Hour
} }
} }
...@@ -167,7 +167,7 @@ func readOptions(cx *cli.Context, config *Config) (err error) { ...@@ -167,7 +167,7 @@ func readOptions(cx *cli.Context, config *Config) (err error) {
config.ProxyProtocol = cx.Bool("proxy-protocol") config.ProxyProtocol = cx.Bool("proxy-protocol")
} }
if cx.IsSet("refresh-sessions") { if cx.IsSet("refresh-sessions") {
config.RefreshSession = cx.Bool("refresh-sessions") config.RefreshSessions = cx.Bool("refresh-sessions")
} }
if cx.IsSet("json-logging") { if cx.IsSet("json-logging") {
config.LogJSONFormat = cx.Bool("json-logging") config.LogJSONFormat = cx.Bool("json-logging")
......
...@@ -41,7 +41,7 @@ resources: ...@@ -41,7 +41,7 @@ resources:
methods: methods:
- GET - GET
# a list of roles the user must have in order to accces urls under the above # a list of roles the user must have in order to accces urls under the above
roles_allowed: roles:
- openvpn:vpn-user - openvpn:vpn-user
- openvpn:prod-vpn - openvpn:prod-vpn
- url: /admin/white_listed - url: /admin/white_listed
...@@ -50,6 +50,6 @@ resources: ...@@ -50,6 +50,6 @@ resources:
- url: /admin - url: /admin
methods: methods:
- GET - GET
roles_allowed: roles:
- openvpn:vpn-user - openvpn:vpn-user
- openvpn:prod-vpn - openvpn:prod-vpn
...@@ -63,8 +63,8 @@ type Resource struct { ...@@ -63,8 +63,8 @@ type Resource struct {
Methods []string `json:"methods" yaml:"methods"` Methods []string `json:"methods" yaml:"methods"`
// WhiteListed permits the prefix through // WhiteListed permits the prefix through
WhiteListed bool `json:"white-listed" yaml:"white-listed"` WhiteListed bool `json:"white-listed" yaml:"white-listed"`
// RolesAllowed the roles required to access this url // Roles the roles required to access this url
RolesAllowed []string `json:"roles_allowed" yaml:"roles_allowed"` Roles []string `json:"roles" yaml:"roles"`
} }
// Config is the configuration for the proxy // Config is the configuration for the proxy
...@@ -81,8 +81,8 @@ type Config struct { ...@@ -81,8 +81,8 @@ type Config struct {
Secret string `json:"secret" yaml:"secret"` Secret string `json:"secret" yaml:"secret"`
// RedirectionURL the redirection url // RedirectionURL the redirection url
RedirectionURL string `json:"redirection_url" yaml:"redirection_url"` RedirectionURL string `json:"redirection_url" yaml:"redirection_url"`
// RefreshSession enabled refresh access // RefreshSessions enabled refresh access
RefreshSession bool `json:"refresh_session" yaml:"refresh_session"` RefreshSessions bool `json:"refresh_sessions" yaml:"refresh_sessions"`
// EncryptionKey is the encryption key used to encrypt the refresh token // EncryptionKey is the encryption key used to encrypt the refresh token
EncryptionKey string `json:"encryption_key" yaml:"encryption_key"` EncryptionKey string `json:"encryption_key" yaml:"encryption_key"`
// MaxSession the max session for refreshing // MaxSession the max session for refreshing
......
...@@ -148,7 +148,7 @@ func (r *KeycloakProxy) authenticationHandler() gin.HandlerFunc { ...@@ -148,7 +148,7 @@ func (r *KeycloakProxy) authenticationHandler() gin.HandlerFunc {
session, isBearer, err := r.getSessionToken(cx) session, isBearer, err := r.getSessionToken(cx)
if err != nil { if err != nil {
// step: there isn't a session cookie, do we have refresh session cookie? // step: there isn't a session cookie, do we have refresh session cookie?
if err == ErrSessionNotFound && r.config.RefreshSession && !isBearer { if err == ErrSessionNotFound && r.config.RefreshSessions && !isBearer {
session, err = r.refreshUserSessionToken(cx) session, err = r.refreshUserSessionToken(cx)
if err != nil { if err != nil {
log.WithFields(log.Fields{"error": err.Error()}).Errorf("failed to refresh the access token") log.WithFields(log.Fields{"error": err.Error()}).Errorf("failed to refresh the access token")
...@@ -223,7 +223,7 @@ func (r *KeycloakProxy) authenticationHandler() gin.HandlerFunc { ...@@ -223,7 +223,7 @@ func (r *KeycloakProxy) authenticationHandler() gin.HandlerFunc {
} }
// step: are we refreshing the access tokens? // step: are we refreshing the access tokens?
if !r.config.RefreshSession { if !r.config.RefreshSessions {
log.WithFields(fields).Errorf("the session has expired and token refreshing is disabled") log.WithFields(fields).Errorf("the session has expired and token refreshing is disabled")
r.redirectToAuthorization(cx) r.redirectToAuthorization(cx)
return return
...@@ -269,8 +269,8 @@ func (r *KeycloakProxy) admissionHandler() gin.HandlerFunc { ...@@ -269,8 +269,8 @@ func (r *KeycloakProxy) admissionHandler() gin.HandlerFunc {
identity := uc.(*userContext) identity := uc.(*userContext)
// step: we need to check the roles // step: we need to check the roles
if roles := len(resource.RolesAllowed); roles > 0 { if roles := len(resource.Roles); roles > 0 {
if !hasRoles(resource.RolesAllowed, identity.roles) { if !hasRoles(resource.Roles, identity.roles) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"access": "denied", "access": "denied",
"username": identity.name, "username": identity.name,
...@@ -419,7 +419,7 @@ func (r *KeycloakProxy) oauthAuthorizationHandler(cx *gin.Context) { ...@@ -419,7 +419,7 @@ func (r *KeycloakProxy) oauthAuthorizationHandler(cx *gin.Context) {
// step: get the access type required // step: get the access type required
accessType := "" accessType := ""
if r.config.RefreshSession { if r.config.RefreshSessions {
accessType = "offline" accessType = "offline"
} }
...@@ -496,7 +496,7 @@ func (r *KeycloakProxy) oauthCallbackHandler(cx *gin.Context) { ...@@ -496,7 +496,7 @@ func (r *KeycloakProxy) oauthCallbackHandler(cx *gin.Context) {
} }
// step: do we have session data to persist? // step: do we have session data to persist?
if r.config.RefreshSession { if r.config.RefreshSessions {
// step: parse the token // step: parse the token
_, ident, err := r.parseToken(response.RefreshToken) _, ident, err := r.parseToken(response.RefreshToken)
if err != nil { if err != nil {
......
...@@ -36,7 +36,7 @@ func TestEntrypointHandlerSecure(t *testing.T) { ...@@ -36,7 +36,7 @@ func TestEntrypointHandlerSecure(t *testing.T) {
{ {
URL: "/", URL: "/",
Methods: []string{"POST"}, Methods: []string{"POST"},
RolesAllowed: []string{"test"}, Roles: []string{"test"},
}, },
}) })
...@@ -180,17 +180,17 @@ func TestAdmissionHandlerRoles(t *testing.T) { ...@@ -180,17 +180,17 @@ func TestAdmissionHandlerRoles(t *testing.T) {
{ {
URL: "/admin", URL: "/admin",
Methods: []string{"ANY"}, Methods: []string{"ANY"},
RolesAllowed: []string{"admin"}, Roles: []string{"admin"},
}, },
{ {
URL: "/test", URL: "/test",
Methods: []string{"GET"}, Methods: []string{"GET"},
RolesAllowed: []string{"test"}, Roles: []string{"test"},
}, },
{ {
URL: "/either", URL: "/either",
Methods: []string{"ANY"}, Methods: []string{"ANY"},
RolesAllowed: []string{"admin", "test"}, Roles: []string{"admin", "test"},
}, },
{ {
URL: "/", URL: "/",
......
...@@ -26,8 +26,8 @@ func (r *Resource) isValid() error { ...@@ -26,8 +26,8 @@ func (r *Resource) isValid() error {
if r.Methods == nil { if r.Methods == nil {
r.Methods = make([]string, 0) r.Methods = make([]string, 0)
} }
if r.RolesAllowed == nil { if r.Roles == nil {
r.RolesAllowed = make([]string, 0) r.Roles = make([]string, 0)
} }
if strings.HasPrefix(r.URL, oauthURL) { if strings.HasPrefix(r.URL, oauthURL) {
...@@ -56,7 +56,7 @@ func (r *Resource) isValid() error { ...@@ -56,7 +56,7 @@ func (r *Resource) isValid() error {
// getRoles gets a list of roles // getRoles gets a list of roles
func (r Resource) getRoles() string { func (r Resource) getRoles() string {
return strings.Join(r.RolesAllowed, ",") return strings.Join(r.Roles, ",")
} }
func (r Resource) String() string { func (r Resource) String() string {
...@@ -67,10 +67,10 @@ func (r Resource) String() string { ...@@ -67,10 +67,10 @@ func (r Resource) String() string {
return fmt.Sprintf("uri: %s, white-listed", r.URL) return fmt.Sprintf("uri: %s, white-listed", r.URL)
} }
if len(r.RolesAllowed) <= 0 { if len(r.Roles) <= 0 {
roles = "authentication only" roles = "authentication only"
} else { } else {
methods = strings.Join(r.RolesAllowed, ",") methods = strings.Join(r.Roles, ",")
} }
if len(r.Methods) <= 0 { if len(r.Methods) <= 0 {
......
...@@ -53,7 +53,7 @@ func TestIsValid(t *testing.T) { ...@@ -53,7 +53,7 @@ func TestIsValid(t *testing.T) {
func TestResourceString(t *testing.T) { func TestResourceString(t *testing.T) {
resource := &Resource{ resource := &Resource{
RolesAllowed: []string{"1", "2", "3"}, Roles: []string{"1", "2", "3"},
} }
if s := resource.String(); s == "" { if s := resource.String(); s == "" {
t.Errorf("we should have recieved a string") t.Errorf("we should have recieved a string")
...@@ -62,7 +62,7 @@ func TestResourceString(t *testing.T) { ...@@ -62,7 +62,7 @@ func TestResourceString(t *testing.T) {
func TestGetRoles(t *testing.T) { func TestGetRoles(t *testing.T) {
resource := &Resource{ resource := &Resource{
RolesAllowed: []string{"1", "2", "3"}, Roles: []string{"1", "2", "3"},
} }
if resource.getRoles() != "1,2,3" { if resource.getRoles() != "1,2,3" {
......
...@@ -58,39 +58,39 @@ func newFakeKeycloakProxy(t *testing.T) *KeycloakProxy { ...@@ -58,39 +58,39 @@ func newFakeKeycloakProxy(t *testing.T) *KeycloakProxy {
EncryptionKey: "AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j", EncryptionKey: "AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j",
SkipTokenVerification: true, SkipTokenVerification: true,
Scopes: []string{}, Scopes: []string{},
RefreshSession: false, RefreshSessions: false,
Resources: []*Resource{ Resources: []*Resource{
{ {
URL: fakeAdminRoleURL, URL: fakeAdminRoleURL,
Methods: []string{"GET"}, Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole}, Roles: []string{fakeAdminRole},
}, },
{ {
URL: fakeTestRoleURL, URL: fakeTestRoleURL,
Methods: []string{"GET"}, Methods: []string{"GET"},
RolesAllowed: []string{fakeTestRole}, Roles: []string{fakeTestRole},
}, },
{ {
URL: fakeTestAdminRolesURL, URL: fakeTestAdminRolesURL,
Methods: []string{"GET"}, Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole, fakeTestRole}, Roles: []string{fakeAdminRole, fakeTestRole},
}, },
{ {
URL: fakeTestWhitelistedURL, URL: fakeTestWhitelistedURL,
WhiteListed: true, WhiteListed: true,
Methods: []string{}, Methods: []string{},
RolesAllowed: []string{}, Roles: []string{},
}, },
{ {
URL: fakeAuthAllURL, URL: fakeAuthAllURL,
Methods: []string{"ANY"}, Methods: []string{"ANY"},
RolesAllowed: []string{}, Roles: []string{},
}, },
{ {
URL: fakeTestWhitelistedURL, URL: fakeTestWhitelistedURL,
WhiteListed: true, WhiteListed: true,
Methods: []string{}, Methods: []string{},
RolesAllowed: []string{}, Roles: []string{},
}, },
}, },
}, },
......
...@@ -223,7 +223,7 @@ func TestDecodeResource(t *testing.T) { ...@@ -223,7 +223,7 @@ func TestDecodeResource(t *testing.T) {
Ok: true, Ok: true,
Resource: &Resource{ Resource: &Resource{
URL: "/admin/sso", URL: "/admin/sso",
RolesAllowed: []string{"test", "test1"}, Roles: []string{"test", "test1"},
}, },
}, },
{ {
...@@ -231,7 +231,7 @@ func TestDecodeResource(t *testing.T) { ...@@ -231,7 +231,7 @@ func TestDecodeResource(t *testing.T) {
Ok: true, Ok: true,
Resource: &Resource{ Resource: &Resource{
URL: "/admin/sso", URL: "/admin/sso",
RolesAllowed: []string{"test", "test1"}, Roles: []string{"test", "test1"},
Methods: []string{"GET", "POST"}, Methods: []string{"GET", "POST"},
}, },
}, },
......
...@@ -305,7 +305,7 @@ func decodeResource(v string) (*Resource, error) { ...@@ -305,7 +305,7 @@ func decodeResource(v string) (*Resource, error) {
case "methods": case "methods":
resource.Methods = strings.Split(kp[1], ",") resource.Methods = strings.Split(kp[1], ",")
case "roles": case "roles":
resource.RolesAllowed = strings.Split(kp[1], ",") resource.Roles = strings.Split(kp[1], ",")
case "white-listed": case "white-listed":
value, err := strconv.ParseBool(kp[1]) value, err := strconv.ParseBool(kp[1])
if err != nil { if err != nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment