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

Merge pull request #22 from gambol99/cors_support

- adding the ability to set cross origin resource sharing headers
parents abdfe8d8 c572946a
Branches
Tags v1.0.0-rc1
No related merge requests found
......@@ -39,6 +39,11 @@ func newDefaultConfig() *Config {
MaxSession: time.Duration(1) * time.Hour,
TagData: make(map[string]string, 0),
ClaimsMatch: make(map[string]string, 0),
CORSConfig: &CORS{
Origins: []string{},
Methods: []string{},
Headers: []string{},
},
}
}
......@@ -209,6 +214,24 @@ func readOptions(cx *cli.Context, config *Config) (err error) {
return err
}
}
if cx.IsSet("header") {
config.Header, err = decodeKeyPairs(cx.StringSlice("header"))
if err != nil {
return err
}
}
if cx.IsSet("cors-origins") {
config.CORSConfig.Origins = cx.StringSlice("cors-origins")
}
if cx.IsSet("cors-methods") {
config.CORSConfig.Methods = cx.StringSlice("cors-methods")
}
if cx.IsSet("cors-headers") {
config.CORSConfig.Headers = cx.StringSlice("cors-headers")
}
if cx.IsSet("cors-max-age") {
config.CORSConfig.MaxAge = cx.Duration("cors-max-age")
}
if cx.IsSet("resource") {
for _, x := range cx.StringSlice("resource") {
resource, err := decodeResource(x)
......@@ -327,6 +350,22 @@ func getOptions() []cli.Flag {
Usage: "if refresh sessions are enabled we can limit their duration via this",
Value: defaults.MaxSession,
},
cli.StringSliceFlag{
Name: "cors-origins",
Usage: "a set of origins to add to the CORS access control (Access-Control-Allow-Origin)",
},
cli.StringSliceFlag{
Name: "cors-headers",
Usage: "a set of headers to add to the CORS access control (Access-Control-Allow-Headers)",
},
cli.StringSliceFlag{
Name: "cors-methods",
Usage: "the method permitted in the access control (Access-Control-Allow-Methods)",
},
cli.DurationFlag{
Name: "cors-max-age",
Usage: "the max age applied to cors headers (Access-Control-Max-Age)",
},
cli.BoolFlag{
Name: "skip-token-verification",
Usage: "testing purposes ONLY, the option allows you to bypass the token verification, expiration and roles are still enforced",
......
......@@ -67,6 +67,18 @@ type Resource struct {
Roles []string `json:"roles" yaml:"roles"`
}
// CORS controls
type CORS struct {
// Origins is a list of origins permitted
Origins []string `json:"origins" yaml:"origins"`
// Methods is a set of access control methods
Methods []string `json:"methods" yaml:"methods"`
// Headers is a set of cors headers
Headers []string `json:"headers" yaml:"headers"`
// MaxAge is the age for CORS
MaxAge time.Duration `json:"max-age" yaml:"max-age"`
}
// Config is the configuration for the proxy
type Config struct {
// LogRequests indicates if we should log all the requests
......@@ -103,6 +115,10 @@ type Config struct {
Upstream string `json:"upstream" yaml:"upstream"`
// TagData is passed to the templates
TagData map[string]string `json:"TagData" yaml:"TagData"`
// CORS permits adding headers to the /oauth handlers
CORSConfig *CORS `json:"cors" yaml:"cors"`
// Header permits adding customs headers across the board
Header map[string]string `json:"headers" yaml:"headers"`
// Scopes is a list of scope we should request
Scopes []string `json:"scopes" yaml:"scopes"`
// Resources is a list of protected resources
......
......@@ -22,6 +22,7 @@ import (
"strings"
"time"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/gambol99/go-oidc/jose"
"github.com/gambol99/go-oidc/oauth2"
......@@ -113,6 +114,11 @@ func (r *KeycloakProxy) entryPointHandler() gin.HandlerFunc {
// step: pass into the authentication and admission handlers
cx.Next()
// step: add a custom headers to the request
for k, v := range r.config.Header {
cx.Request.Header.Set(k, v)
}
// step: check the request has not been aborted and if not, proxy request
if !cx.IsAborted() {
r.proxyHandler(cx)
......@@ -446,6 +452,9 @@ func (r *KeycloakProxy) oauthAuthorizationHandler(cx *gin.Context) {
return
}
// step: add the cors headers
r.corsAccessHeaders(cx)
// step: get the redirection url
r.redirectToURL(redirectionURL, cx)
}
......@@ -555,6 +564,9 @@ func (r *KeycloakProxy) oauthCallbackHandler(cx *gin.Context) {
}
}
// step: add the cors headers
r.corsAccessHeaders(cx)
r.redirectToURL(state, cx)
}
......@@ -564,3 +576,21 @@ func (r *KeycloakProxy) oauthCallbackHandler(cx *gin.Context) {
func (r *KeycloakProxy) healthHandler(cx *gin.Context) {
cx.String(http.StatusOK, "OK")
}
// corsAccessHeaders adds the cors access controls to the oauth responses
func (r *KeycloakProxy) corsAccessHeaders(cx *gin.Context) {
cors := r.config.CORSConfig
if len(cors.Origins) > 0 {
cx.Writer.Header().Set("Access-Control-Allow-Origin", strings.Join(cors.Origins, ","))
}
if len(cors.Methods) > 0 {
cx.Writer.Header().Set("Access-Control-Allow-Methods", strings.Join(cors.Methods, ","))
}
if len(cors.Headers) > 0 {
cx.Writer.Header().Set("Access-Control-Allow-Headers", strings.Join(cors.Headers, ","))
}
if cors.MaxAge > 0 {
cx.Writer.Header().Set("Access-Control-Max-Age",
fmt.Sprintf("%d", int(cors.MaxAge.Seconds())))
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment