@@ -1750,6 +1750,8 @@ func TestRequestSignature(t *testing.T) {
1751func TestGetRedirect(t *testing.T) {
1751func TestGetRedirect(t *testing.T) {
1752 opts := baseTestOptions()
1752 opts := baseTestOptions()
1753+ opts.WhitelistDomains = append(opts.WhitelistDomains, ".example.com")
1754+ opts.WhitelistDomains = append(opts.WhitelistDomains, ".example.com:8443")
1753 err := validation.Validate(opts)
1755 err := validation.Validate(opts)
1754 assert.NoError(t, err)
1756 assert.NoError(t, err)
1755 require.NotEmpty(t, opts.ProxyPrefix)
1757 require.NotEmpty(t, opts.ProxyPrefix)
@@ -1761,27 +1763,145 @@ func TestGetRedirect(t *testing.T) {
1761 tests := []struct {
1763 tests := []struct {
1762 name string
1764 name string
1763 url string
1765 url string
1766+ headers map[string]string
1764 expectedRedirect string
1768 expectedRedirect string
1767 name: "request outside of ProxyPrefix redirects to original URL",
1771 name: "request outside of ProxyPrefix redirects to original URL",
1768 url: "/foo/bar",
1772 url: "/foo/bar",
1774+ reverseProxy: false,
1769 expectedRedirect: "/foo/bar",
1775 expectedRedirect: "/foo/bar",
1772 name: "request with query preserves query",
1778 name: "request with query preserves query",
1773 url: "/foo?bar",
1779 url: "/foo?bar",
1781+ reverseProxy: false,
1774 expectedRedirect: "/foo?bar",
1782 expectedRedirect: "/foo?bar",
1777 name: "request under ProxyPrefix redirects to root",
1785 name: "request under ProxyPrefix redirects to root",
1778 url: proxy.ProxyPrefix + "/foo/bar",
1786 url: proxy.ProxyPrefix + "/foo/bar",
1788+ reverseProxy: false,
1779 expectedRedirect: "/",
1789 expectedRedirect: "/",
1792+ name: "proxied request outside of ProxyPrefix redirects to proxied URL",
1793+ url: "https://oauth.example.com/foo/bar",
1794+ headers: map[string]string{
1795+ "X-Forwarded-Proto": "https",
1796+ "X-Forwarded-Host": "a-service.example.com",
1797+ "X-Forwarded-Uri": "/foo/bar",
1799+ reverseProxy: true,
1800+ expectedRedirect: "https://a-service.example.com/foo/bar",
1803+ name: "non-proxied request with spoofed proxy headers wouldn't redirect",
1804+ url: "https://oauth.example.com/foo?bar",
1805+ headers: map[string]string{
1806+ "X-Forwarded-Proto": "https",
1807+ "X-Forwarded-Host": "a-service.example.com",
1808+ "X-Forwarded-Uri": "/foo/bar",
1810+ reverseProxy: false,
1811+ expectedRedirect: "/foo?bar",
1814+ name: "proxied request under ProxyPrefix redirects to root",
1815+ url: "https://oauth.example.com" + proxy.ProxyPrefix + "/foo/bar",
1816+ headers: map[string]string{
1817+ "X-Forwarded-Proto": "https",
1818+ "X-Forwarded-Host": "a-service.example.com",
1819+ "X-Forwarded-Uri": proxy.ProxyPrefix + "/foo/bar",
1821+ reverseProxy: true,
1822+ expectedRedirect: "https://a-service.example.com/",
1825+ name: "proxied request with port under ProxyPrefix redirects to root",
1826+ url: "https://oauth.example.com" + proxy.ProxyPrefix + "/foo/bar",
1827+ headers: map[string]string{
1828+ "X-Forwarded-Proto": "https",
1829+ "X-Forwarded-Host": "a-service.example.com:8443",
1830+ "X-Forwarded-Uri": proxy.ProxyPrefix + "/foo/bar",
1832+ reverseProxy: true,
1833+ expectedRedirect: "https://a-service.example.com:8443/",
1836+ name: "proxied request with missing uri header would still redirect to desired redirect",
1837+ url: "https://oauth.example.com/foo?bar",
1838+ headers: map[string]string{
1839+ "X-Forwarded-Proto": "https",
1840+ "X-Forwarded-Host": "a-service.example.com",
1842+ reverseProxy: true,
1843+ expectedRedirect: "https://a-service.example.com/foo?bar",
1846+ name: "request with headers proxy not being set (and reverse proxy enabled) would still redirect to desired redirect",
1847+ url: "https://oauth.example.com/foo?bar",
1849+ reverseProxy: true,
1850+ expectedRedirect: "/foo?bar",
1853+ name: "proxied request with X-Auth-Request-Redirect being set outside of ProxyPrefix redirects to proxied URL",
1854+ url: "https://oauth.example.com/foo/bar",
1855+ headers: map[string]string{
1856+ "X-Auth-Request-Redirect": "https://a-service.example.com/foo/bar",
1857+ "X-Forwarded-Proto": "",
1858+ "X-Forwarded-Host": "",
1859+ "X-Forwarded-Uri": "",
1861+ reverseProxy: true,
1862+ expectedRedirect: "https://a-service.example.com/foo/bar",
1865+ name: "proxied request with rd query string redirects to proxied URL",
1866+ url: "https://oauth.example.com/foo/bar?rd=https%3A%2F%2Fa%2Dservice%2Eexample%2Ecom%2Ffoo%2Fbar",
1868+ reverseProxy: false,
1869+ expectedRedirect: "https://a-service.example.com/foo/bar",
1872+ name: "proxied request with rd query string and all headers set (and reverse proxy not enabled) redirects to proxied URL on rd query string",
1873+ url: "https://oauth.example.com/foo/bar?rd=https%3A%2F%2Fa%2Dservice%2Eexample%2Ecom%2Ffoo%2Fjazz",
1874+ headers: map[string]string{
1875+ "X-Auth-Request-Redirect": "https://a-service.example.com/foo/baz",
1876+ "X-Forwarded-Proto": "http",
1877+ "X-Forwarded-Host": "another-service.example.com",
1878+ "X-Forwarded-Uri": "/seasons/greetings",
1880+ reverseProxy: false,
1881+ expectedRedirect: "https://a-service.example.com/foo/jazz",
1884+ name: "proxied request with rd query string and some headers set redirects to proxied URL on rd query string",
1885+ url: "https://oauth.example.com/foo/bar?rd=https%3A%2F%2Fa%2Dservice%2Eexample%2Ecom%2Ffoo%2Fbaz",
1886+ headers: map[string]string{
1887+ "X-Auth-Request-Redirect": "",
1888+ "X-Forwarded-Proto": "https",
1889+ "X-Forwarded-Host": "another-service.example.com",
1890+ "X-Forwarded-Uri": "/seasons/greetings",
1892+ reverseProxy: true,
1893+ expectedRedirect: "https://a-service.example.com/foo/baz",
1782 for _, tt := range tests {
1896 for _, tt := range tests {
1783 t.Run(tt.name, func(t *testing.T) {
1897 t.Run(tt.name, func(t *testing.T) {
1784 req, _ := http.NewRequest("GET", tt.url, nil)
1898 req, _ := http.NewRequest("GET", tt.url, nil)
1899+ for header, value := range tt.headers {
1901+ req.Header.Add(header, value)
1904+ proxy.ReverseProxy = tt.reverseProxy
1785 redirect, err := proxy.GetRedirect(req)
1905 redirect, err := proxy.GetRedirect(req)
1787 assert.NoError(t, err)
1907 assert.NoError(t, err)