@@ -1750,6 +1750,8 @@ func TestRequestSignature(t *testing.T) {
17501750
17511751func TestGetRedirect(t *testing.T) {
17521752 opts := baseTestOptions()
1753+ opts.WhitelistDomains = append(opts.WhitelistDomains, ".example.com")
1754+ opts.WhitelistDomains = append(opts.WhitelistDomains, ".example.com:8443")
17531755 err := validation.Validate(opts)
17541756 assert.NoError(t, err)
17551757 require.NotEmpty(t, opts.ProxyPrefix)
@@ -1761,27 +1763,145 @@ func TestGetRedirect(t *testing.T) {
17611763 tests := []struct {
17621764 name string
17631765 url string
1766+ headers map[string]string
1767+ reverseProxy bool
17641768 expectedRedirect string
17651769 }{
17661770 {
17671771 name: "request outside of ProxyPrefix redirects to original URL",
17681772 url: "/foo/bar",
1773+ headers: nil,
1774+ reverseProxy: false,
17691775 expectedRedirect: "/foo/bar",
17701776 },
17711777 {
17721778 name: "request with query preserves query",
17731779 url: "/foo?bar",
1780+ headers: nil,
1781+ reverseProxy: false,
17741782 expectedRedirect: "/foo?bar",
17751783 },
17761784 {
17771785 name: "request under ProxyPrefix redirects to root",
17781786 url: proxy.ProxyPrefix + "/foo/bar",
1787+ headers: nil,
1788+ reverseProxy: false,
17791789 expectedRedirect: "/",
17801790 },
1791+ {
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",
1798+ },
1799+ reverseProxy: true,
1800+ expectedRedirect: "https://a-service.example.com/foo/bar",
1801+ },
1802+ {
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",
1809+ },
1810+ reverseProxy: false,
1811+ expectedRedirect: "/foo?bar",
1812+ },
1813+ {
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",
1820+ },
1821+ reverseProxy: true,
1822+ expectedRedirect: "https://a-service.example.com/",
1823+ },
1824+ {
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",
1831+ },
1832+ reverseProxy: true,
1833+ expectedRedirect: "https://a-service.example.com:8443/",
1834+ },
1835+ {
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",
1841+ },
1842+ reverseProxy: true,
1843+ expectedRedirect: "https://a-service.example.com/foo?bar",
1844+ },
1845+ {
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",
1848+ headers: nil,
1849+ reverseProxy: true,
1850+ expectedRedirect: "/foo?bar",
1851+ },
1852+ {
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": "",
1860+ },
1861+ reverseProxy: true,
1862+ expectedRedirect: "https://a-service.example.com/foo/bar",
1863+ },
1864+ {
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",
1867+ headers: nil,
1868+ reverseProxy: false,
1869+ expectedRedirect: "https://a-service.example.com/foo/bar",
1870+ },
1871+ {
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",
1879+ },
1880+ reverseProxy: false,
1881+ expectedRedirect: "https://a-service.example.com/foo/jazz",
1882+ },
1883+ {
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",
1891+ },
1892+ reverseProxy: true,
1893+ expectedRedirect: "https://a-service.example.com/foo/baz",
1894+ },
17811895 }
17821896 for _, tt := range tests {
17831897 t.Run(tt.name, func(t *testing.T) {
17841898 req, _ := http.NewRequest("GET", tt.url, nil)
1899+ for header, value := range tt.headers {
1900+ if value != "" {
1901+ req.Header.Add(header, value)
1902+ }
1903+ }
1904+ proxy.ReverseProxy = tt.reverseProxy
17851905 redirect, err := proxy.GetRedirect(req)
17861906
17871907 assert.NoError(t, err)