Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-cloud-netflix
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
spring-cloud-netflix
Commits
df530391
Unverified
Commit
df530391
authored
Apr 07, 2016
by
Spencer Gibb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add global zuul sensitiveHeaders option.
Route specific sensitiveHeaders override global. fixes gh-944
parent
4479a2b2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
93 additions
and
25 deletions
+93
-25
spring-cloud-netflix.adoc
docs/src/main/asciidoc/spring-cloud-netflix.adoc
+2
-0
ZuulProperties.java
...gframework/cloud/netflix/zuul/filters/ZuulProperties.java
+12
-2
PreDecorationFilter.java
...k/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java
+18
-17
ZuulPropertiesTests.java
...ework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java
+23
-5
PreDecorationFilterTests.java
...ud/netflix/zuul/filters/pre/PreDecorationFilterTests.java
+38
-1
No files found.
docs/src/main/asciidoc/spring-cloud-netflix.adoc
View file @
df530391
...
...
@@ -1267,6 +1267,8 @@ route, e.g.
url: https://dowstream
----
Sensitive headers can also be set globally setting `zuul.sensitiveHeaders`. If `sensitiveHeaders` is set on a route, this will override the global `sensitiveHeaders` setting.
NOTE: this is the default value for `sensitiveHeaders`, so you don'
t
need
to
set
it
unless
you
want
it
to
be
different
.
N
.
B
.
this
is
new
in
Spring
Cloud
Netflix
1.1
(
in
1.0
the
user
had
no
control
over
headers
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java
View file @
df530391
...
...
@@ -115,6 +115,17 @@ public class ZuulProperties {
*/
private
boolean
removeSemicolonContent
=
true
;
/**
* List of sensitive headers that are not passed to downstream requests. Defaults
* to a "safe" set of headers that commonly contain user credentials. It's OK to
* remove those from the list if the downstream service is part of the same system
* as the proxy, so they are sharing authentication data. If using a physical URL
* outside your own domain, then generally it would be a bad idea to leak user
* credentials.
*/
private
Set
<
String
>
sensitiveHeaders
=
new
LinkedHashSet
<>(
Arrays
.
asList
(
"Cookie"
,
"Set-Cookie"
,
"Authorization"
));
public
Set
<
String
>
getIgnoredHeaders
()
{
Set
<
String
>
ignoredHeaders
=
new
LinkedHashSet
<>(
this
.
ignoredHeaders
);
if
(
ClassUtils
.
isPresent
(
...
...
@@ -193,8 +204,7 @@ public class ZuulProperties {
* outside your own domain, then generally it would be a bad idea to leak user
* credentials.
*/
private
Set
<
String
>
sensitiveHeaders
=
new
LinkedHashSet
<>(
Arrays
.
asList
(
"Cookie"
,
"Set-Cookie"
,
"Authorization"
));
private
Set
<
String
>
sensitiveHeaders
=
new
LinkedHashSet
<>();
public
ZuulRoute
(
String
text
)
{
String
location
=
null
;
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java
View file @
df530391
...
...
@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.zuul.filters.pre;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper
;
import
org.springframework.cloud.netflix.zuul.filters.Route
;
import
org.springframework.cloud.netflix.zuul.filters.RouteLocator
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties
;
...
...
@@ -37,21 +38,18 @@ public class PreDecorationFilter extends ZuulFilter {
private
RouteLocator
routeLocator
;
private
boolean
addProxyHeaders
;
private
String
dispatcherServletPath
;
private
String
zuulServletPath
;
private
ZuulProperties
properties
;
private
UrlPathHelper
urlPathHelper
=
new
UrlPathHelper
();
public
PreDecorationFilter
(
RouteLocator
routeLocator
,
String
dispatcherServletPath
,
ZuulProperties
zuulP
roperties
)
{
String
dispatcherServletPath
,
ZuulProperties
p
roperties
)
{
this
.
routeLocator
=
routeLocator
;
this
.
addProxyHeaders
=
zuulProperties
.
isAddProxyHeaders
()
;
this
.
urlPathHelper
.
setRemoveSemicolonContent
(
zuulP
roperties
.
isRemoveSemicolonContent
());
this
.
properties
=
properties
;
this
.
urlPathHelper
.
setRemoveSemicolonContent
(
p
roperties
.
isRemoveSemicolonContent
());
this
.
dispatcherServletPath
=
dispatcherServletPath
;
this
.
zuulServletPath
=
zuulProperties
.
getServletPath
();
}
@Override
...
...
@@ -67,9 +65,8 @@ public class PreDecorationFilter extends ZuulFilter {
@Override
public
boolean
shouldFilter
()
{
RequestContext
ctx
=
RequestContext
.
getCurrentContext
();
return
!
ctx
.
containsKey
(
"forward.to"
)
// another filter has already forwarded
&&
!
ctx
.
containsKey
(
"serviceId"
);
// another filter has already determined
// serviceId
return
!
ctx
.
containsKey
(
"forward.to"
)
// a filter has already forwarded
&&
!
ctx
.
containsKey
(
"serviceId"
);
// a filter has already determined serviceId
}
@Override
...
...
@@ -83,7 +80,11 @@ public class PreDecorationFilter extends ZuulFilter {
if
(
location
!=
null
)
{
ctx
.
put
(
"requestURI"
,
route
.
getPath
());
ctx
.
put
(
"proxy"
,
route
.
getId
());
ctx
.
put
(
"ignoredHeaders"
,
route
.
getSensitiveHeaders
());
if
(
route
.
getSensitiveHeaders
().
isEmpty
())
{
ctx
.
put
(
ProxyRequestHelper
.
IGNORED_HEADERS
,
this
.
properties
.
getSensitiveHeaders
());
}
else
{
ctx
.
put
(
ProxyRequestHelper
.
IGNORED_HEADERS
,
route
.
getSensitiveHeaders
());
}
if
(
route
.
getRetryable
()
!=
null
)
{
ctx
.
put
(
"retryable"
,
route
.
getRetryable
());
...
...
@@ -105,7 +106,7 @@ public class PreDecorationFilter extends ZuulFilter {
ctx
.
setRouteHost
(
null
);
ctx
.
addOriginResponseHeader
(
"X-Zuul-ServiceId"
,
location
);
}
if
(
this
.
addProxyHeaders
)
{
if
(
this
.
properties
.
isAddProxyHeaders
()
)
{
ctx
.
addZuulRequestHeader
(
"X-Forwarded-Host"
,
ctx
.
getRequest
().
getServerName
());
ctx
.
addZuulRequestHeader
(
"X-Forwarded-Port"
,
...
...
@@ -129,14 +130,14 @@ public class PreDecorationFilter extends ZuulFilter {
}
else
{
log
.
warn
(
"No route found for uri: "
+
requestURI
);
String
fallBackUri
=
requestURI
;
String
fallbackPrefix
=
dispatcherServletPath
;
//default fallback servlet is DispatcherServlet
if
(
RequestUtils
.
isZuulServletRequest
())
{
//remove the Zuul servletPath from the requestUri
log
.
debug
(
"zuulServletPath="
+
zuulServletPath
);
fallBackUri
=
fallBackUri
.
replaceFirst
(
zuulServletPath
,
""
);
log
.
debug
(
"zuulServletPath="
+
this
.
properties
.
getServletPath
()
);
fallBackUri
=
fallBackUri
.
replaceFirst
(
this
.
properties
.
getServletPath
()
,
""
);
log
.
debug
(
"Replaced Zuul servlet path:"
+
fallBackUri
);
}
else
{
//remove the DispatcherServlet servletPath from the requestUri
...
...
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java
View file @
df530391
...
...
@@ -16,8 +16,11 @@
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute
;
...
...
@@ -29,7 +32,17 @@ import static org.junit.Assert.assertTrue;
*/
public
class
ZuulPropertiesTests
{
private
ZuulProperties
zuul
=
new
ZuulProperties
();
private
ZuulProperties
zuul
;
@Before
public
void
setup
()
{
this
.
zuul
=
new
ZuulProperties
();
}
@After
public
void
teardown
()
{
this
.
zuul
=
null
;
}
@Test
public
void
defaultIgnoredHeaders
()
{
...
...
@@ -46,17 +59,22 @@ public class ZuulPropertiesTests {
public
void
defaultSensitiveHeaders
()
{
ZuulRoute
route
=
new
ZuulRoute
(
"foo"
);
this
.
zuul
.
getRoutes
().
put
(
"foo"
,
route
);
assertTrue
(
this
.
zuul
.
getRoutes
().
get
(
"foo"
).
getSensitiveHeaders
()
.
contains
(
"Cookie"
));
assertTrue
(
this
.
zuul
.
getRoutes
().
get
(
"foo"
).
getSensitiveHeaders
().
isEmpty
());
assertTrue
(
this
.
zuul
.
getSensitiveHeaders
().
containsAll
(
Arrays
.
asList
(
"Cookie"
,
"Set-Cookie"
,
"Authorization"
)));
}
@Test
public
void
addSensitiveHeaders
()
{
this
.
zuul
.
setSensitiveHeaders
(
Collections
.
singleton
(
"x-bar"
));
ZuulRoute
route
=
new
ZuulRoute
(
"foo"
);
route
.
setSensitiveHeaders
(
Collections
.
singleton
(
"x-foo"
));
this
.
zuul
.
getRoutes
().
put
(
"foo"
,
route
);
assertFalse
(
this
.
zuul
.
getRoutes
().
get
(
"foo"
).
getSensitiveHeaders
()
.
contains
(
"Cookie"
));
ZuulRoute
foo
=
this
.
zuul
.
getRoutes
().
get
(
"foo"
);
assertTrue
(
foo
.
getSensitiveHeaders
().
contains
(
"x-foo"
));
assertFalse
(
foo
.
getSensitiveHeaders
().
contains
(
"Cookie"
));
assertTrue
(
this
.
zuul
.
getSensitiveHeaders
().
contains
(
"x-bar"
));
assertFalse
(
this
.
zuul
.
getSensitiveHeaders
().
contains
(
"Cookie"
));
}
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java
View file @
df530391
...
...
@@ -16,12 +16,15 @@
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
pre
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Set
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.mockito.Mock
;
import
org.springframework.cloud.client.discovery.DiscoveryClient
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute
;
import
org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator
;
...
...
@@ -31,6 +34,8 @@ import com.netflix.util.Pair;
import
com.netflix.zuul.context.RequestContext
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
MockitoAnnotations
.
initMocks
;
/**
...
...
@@ -236,7 +241,39 @@ public class PreDecorationFilterTests {
this
.
filter
.
run
();
assertEquals
(
"/special/api/bar/1"
,
ctx
.
get
(
"forward.to"
));
}
}
@Test
public
void
sensitiveHeadersOverride
()
throws
Exception
{
this
.
properties
.
setPrefix
(
"/api"
);
this
.
properties
.
setStripPrefix
(
true
);
this
.
properties
.
setSensitiveHeaders
(
Collections
.
singleton
(
"x-bar"
));
this
.
request
.
setRequestURI
(
"/api/foo/1"
);
ZuulRoute
route
=
new
ZuulRoute
(
"/foo/**"
,
"foo"
);
route
.
setSensitiveHeaders
(
Collections
.
singleton
(
"x-foo"
));
this
.
routeLocator
.
addRoute
(
route
);
this
.
filter
.
run
();
RequestContext
ctx
=
RequestContext
.
getCurrentContext
();
@SuppressWarnings
(
"unchecked"
)
Set
<
String
>
sensitiveHeaders
=
(
Set
<
String
>)
ctx
.
get
(
ProxyRequestHelper
.
IGNORED_HEADERS
);
assertTrue
(
"sensitiveHeaders is wrong"
,
sensitiveHeaders
.
containsAll
(
Collections
.
singletonList
(
"x-foo"
)));
assertFalse
(
"sensitiveHeaders is wrong"
,
sensitiveHeaders
.
contains
(
"Cookie"
));
}
@Test
public
void
sensitiveHeadersDefaults
()
throws
Exception
{
this
.
properties
.
setPrefix
(
"/api"
);
this
.
properties
.
setStripPrefix
(
true
);
this
.
properties
.
setSensitiveHeaders
(
Collections
.
singleton
(
"x-bar"
));
this
.
request
.
setRequestURI
(
"/api/foo/1"
);
this
.
routeLocator
.
addRoute
(
"/foo/**"
,
"foo"
);
this
.
filter
.
run
();
RequestContext
ctx
=
RequestContext
.
getCurrentContext
();
@SuppressWarnings
(
"unchecked"
)
Set
<
String
>
sensitiveHeaders
=
(
Set
<
String
>)
ctx
.
get
(
ProxyRequestHelper
.
IGNORED_HEADERS
);
assertTrue
(
"sensitiveHeaders is wrong"
,
sensitiveHeaders
.
containsAll
(
Collections
.
singletonList
(
"x-bar"
)));
assertFalse
(
"sensitiveHeaders is wrong"
,
sensitiveHeaders
.
contains
(
"Cookie"
));
}
private
Object
getHeader
(
List
<
Pair
<
String
,
String
>>
headers
,
String
key
)
{
String
value
=
null
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment