mitreid-connect / OpenID-Connect-Java-Spring-Server

An OpenID Connect reference implementation in Java on the Spring platform.
Other
1.48k stars 765 forks source link

Mixed scheme blocked on Authorize Endpoint #1026

Open merric opened 8 years ago

merric commented 8 years ago

We are testing our app in with an https issuer and are having problems with the authorization endpoint when redirects to login. We are using forceHttps on the server config, but it is still redirecting to with a http uri which is being blocked by tomcat.

jricher commented 8 years ago

I've never seen that behavior, and it should be redirecting based on whatever your issuer value is set to. I'm guessing it's something external to the application. Is there something in a proxy setup that might be causing problems?

mpeddagolla commented 8 years ago

After debugging we found that inside LoginUrlAuthenticationEntryPoint.java , property forceHttps is set to false and there by redirecting the login form to http instead of https. We set the forceHttps = true and issuer in server-config.xml is set to valid https url. We are currently hosting the login screen on our website which is secured. Our understanding is that setting the forceHttps property to true will force the login screen to use https instead of http. Can you please provide some insight here.We are blocked on this since last 2 days. All works good in local environment but when we moved to our test environment we started getting issues displaying login form because login is served as http and there by mixed content on our website

Thank you

jricher commented 8 years ago

That class is provided by Spring Security and doesn't even see the forceHttps property. Are you supplying it with a relative URL for the login URL page?

mpeddagolla commented 8 years ago

Serving login screen with https solved with custom AuthenticationEntryPoint and forceHttps configured. Now I am having mixed content with other pages during login flow. . This has to do with csp policies and we are trying to resolve it.

<security:http disable-url-rewriting="true"
               use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint">

<bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg  name="loginFormUrl" value="/login"/>
    <property name="forceHttps"  value="${authserver.issuer.secured}" />
</bean>

The issue I have currently

Mixed Content: The page at 'https://tenant4dev2.com/classflow/#/login' was loaded over HTTPS, but requested an insecure form action 'http://dev2.com/authserver/authorize?response_type=…mpt=login&redirect_uri=https%3A%2F%2Ftenant44dev2.com%2F'.

My original request below is https and i got 302 as expected to redirected to login but after successful authentication , redirect URI is http instead of https

Request URL:https://dev2.com/authserver/authorize?response_type=code&client_id=classflowclientid&scope=openid&prompt=login&redirect_uri=https%3A%2F%2Ftenant4dev2.com%2F

jricher commented 8 years ago

What do you have set for your issuer? Does it start with https? Are you doing a reverse proxy or cluster? If so, do you have the issuer set to the external URL?

The redirect should only be happening based on that issuer, and if it's set to http and not https then you'll get mixed content like this.

mpeddagolla commented 8 years ago

yes, we are using reverse proxy (we have Apache load balancer in front of our AuthServer basically our overlay app deployed to tomcat). Our issuer is set to https. We set the issuer to URL of the AuthServer i.e. https://AUTHSERVER_URL/ . When request is made to /authorize with https looks like load balancer removed SSL and AuthServer received http request. After successful authentication when it is looking back for any saved request to redirect (authorize in this case) , it is http instead of https. How do we handle this case? I don't understand what you are referring to external URL for issuer.

jricher commented 8 years ago

The issuer needs to point to the URL reachable from outside the load balancer, not the internal one for the server. Inside the server, that should all be handled just fine. There are many instances of this software running behind Apache proxies sitting in front of Tomcat.

Ronnie76er commented 8 years ago

We were having the same issue as here. We had a reverse proxy endpoint set up (in this case, an AWS ELB). While I was working with it, I originally made MitreID Connect run over http, and have the ELB be the SSL termination endpoint. The issuer was set up with https, of the externally facing DNS entry. Our final configuration is SSL even at the MitreID Connect level, so I continued to move on. Once I enabled SSL between the ELB and MitreID Connect, it forwarded correctly.

Just to be clear, it seemed to have something to do with redirects. We were using a basic overlay, with barely anything changed. It seemed to work fine in a lot of instances...loading the entire login page and admin landing pages worked fine. When we would login, however, it would redirect to http instead of https (with the correct server name!)

koen92 commented 7 years ago

I can confirm that this issue still isn't fixed (login calls still redirect to http endpoint, regardless of the issuer URL).

As a workaround we now use an Nginx proxy that rewrites the location field in response headers, see: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Example:

proxy_redirect ~^(http://your-external-dns-uri)(.+)$ https://your-external-dns-uri$2;
jricher commented 7 years ago

@koen92 Is this in the current release (1.3.x)? I haven't been able to replicate it directly yet but we'll look into it again since it seems to keep cropping up.

koen92 commented 7 years ago

@jricher thanks for your reaction! And my apologies for this late reaction (for some reason, Github didn't send me a notification..).

I checked out the latest master of today (1.3.2-SNAPSHOT, ef01d3032e3147e69783e32843672f688a8b25c4 ), and tried to replicate this on a 'clean install/config' (only changed issuer URI/property to https://localhost:443 and running an https proxy on port 443 proxying to localhost:8080 where jetty/mitre is listening). This seems to work (login requests do get a 302 with HTTPS location, so I think that is problem seems to be solved?

I'll check our 'dev' configuration soon (which is a docker container running with an overlay), and hopefully find our configuration error. If I find it, I'll keep you updated.

Thanks again!

jricher commented 7 years ago

We're looking into it with a few different environments. My suspicion is that it's some interaction with the proxy and the container. If we can replicate it we'll try to fix it, if we can't replicate it we'll note it here and close the issue.

mukhtar commented 6 years ago

I also faced this issue. I've investigated it and I resolved it as follows. Note that our deployment runs behind an AWS Elastic Loadbalancer which terminates TLS for us. Therefore, the request coming into Tomcat is from the load balancer over which will be over http.

Tomcat has a RemoteIPValve for this exact use case. The AWS LB adds some headers to the request that it forwards to the application. Tomcat can make use of these headers to construct the request that the application receives if it is instructed to do so using the RemoteIPValve.

To overcome this, I added a context.xml to the META-INF directory with the following:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Valve className="org.apache.catalina.valves.RemoteIpValve"
           remoteIpHeader="x-forwarded-for"
           protocolHeader="x-forwarded-proto"
           portHeader="x-forwarded-port"
           internalProxies="..."
/>
</Context>

where

  1. x-forwarded-for: the IP address of the original request
  2. x-forwarded-proto: the original protocol, for e.g. http or https
  3. x-forwarded-port: the port the original request came on

This way, it will appear to the application that the request is originating from the original client rather than the load balancer.

I wouldn't say that this is an issue in this project at all, so I would suggest closing this issue. The logic for deciding what to redirect the user to is in LoginUrlAuthenticationEntryPoint as pointed out by @mpeddagolla.