]> juplo.de Git - website/blob
fccdf35e6048743d786fa56a57daa4bd31db05c8
[website] /
1 ---
2 _edit_last: "2"
3 _wp_old_date: "2020-03-06"
4 author: kai
5 categories:
6   - howto
7   - java
8   - oauth2
9   - spring
10   - spring-boot
11 classic-editor-remember: classic-editor
12 date: "2020-03-06T22:02:44+00:00"
13 guid: http://juplo.de/?p=1064
14 parent_post_id: null
15 post_id: "1064"
16 title: 'How To Redirect To Spring Security OAuth2 Behind a Gateway/Proxy - Part 1: Running Your  App In Docker'
17 url: /howto-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-running-your-app-in-docker/
18
19 ---
20 ## Switching From Tutorial-Mode (aka POC) To Production Is Hard
21
22 Developing Your first OAuth2-App on [`localhost`](https://www.google.com/search?q=there+no+place+like+%22127.0.0.1%22&tbm=isch&ved=2ahUKEwjF-8XirIHoAhWzIMUKHWcZBJYQ2-cCegQIABAA&oq=there+no+place+like+%22127.0.0.1%22&gs_l=img.3..0i30l3j0i8i30l4.8396.18840..19156...0.0..0.114.2736.30j1......0....1..gws-wiz-img.......35i39j0j0i19j0i30i19j0i8i30i19.joOmqxpmfsw&ei=EeZfXoWvIrPBlAbnspCwCQ&bih=949&biw=1853) with [OAuth2 Boot](https://docs.spring.io/spring-security-oauth2-boot/docs/current/reference/htmlsingle/ "Learn more about OAuth2 Boot") may be easy, ...
23
24 ...but what about running it in **real life**?
25
26 ![Looking for the real life](/wp-uploads/2020/03/real-life-meme-300x297.png)
27
28 This is the first post of a series of Mini-Howtos, that gather some help, to get you started, when switching from localhost to production with SSL and a reverse-proxy (aka gateway) in front of your app, that forwards the requests to your app that listens on a different name/IP, port and protocol.
29
30 ## In This Series We Will...
31
32 1. [Start with](#spring-boot-oauth2) the fantastic official [OAuth2-Tutorial](https://spring.io/guides/tutorials/spring-boot-oauth2/ "You definitely should work through this tutorial first!") from the Spring-Boot folks - _love it!_ \- and [run it as a container in docker](#build-a-docker-image)
33 1. [Hide that behind a reverse-proxy, like in production - _nginx in our case, but could be any pice of software, that can act as a gateway_](/how-to-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-hiding-the-app-behind-a-reverse-proxy-gateway/ "Jump to part 2 and learn how to set up a simulated production-installation")
34  [Show how to debug the oauth2-flow for the whole crap!\
35 Enable SSL for our gateway - because oauth2-providers (like Facebook) are pressing us to do so\
36 Show how to do the same with Facebook, instead of GitHub](/how-to-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-hiding-the-app-behind-a-reverse-proxy-gateway/ "Jump to part 2 and learn how to set up a simulated production-installation")
37
38 [I will also give some advice for those of you, who are new to Docker - _but just enough to enable you to follow_.\
39 \
40 This is **Part 1** of this series, that shows how to **package a Spring-Boot-App as Docker-Image and run it as a container**\
41 **`tut-spring-boot-oauth2/logout`**](/how-to-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-hiding-the-app-behind-a-reverse-proxy-gateway/ "Jump to part 2 and learn how to set up a simulated production-installation")
42
43 [As an example for a simple app, that uses](/how-to-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-hiding-the-app-behind-a-reverse-proxy-gateway/ "Jump to part 2 and learn how to set up a simulated production-installation") [OAuth2](https://tools.ietf.org/html/rfc6749 "Read all about OAuth2 in the RFC 6749") for authentication, we will use the third step of the [Spring-Boot OAuth2-Tutorial](https://spring.io/guides/tutorials/spring-boot-oauth2/ "You definitely should work through this tutorial first!").
44
45 You should work through that tutorial up until that step - called **logout** -, if you have not done yet.
46 This will guide you through programming and setting up a simple app, that uses the [GitHub-API](https://developer.github.com/v3/ "Learn more about the API provided by GitHub") to authenticate its users.
47
48 Especially, it explains, how to **[create and set up a OAuth2-App on GitHub](https://spring.io/guides/tutorials/spring-boot-oauth2/#github-register-application "This links directly to the part of the tutorial, that explains the setup & configuration needed in GitHub Developers")** \- _Do not miss out on that part: You need your own app-ID and -secret and a correctly configured **redirect URI**_.
49
50 You should be able to build the app as JAR and start that with the ID/secret of your GitHub-App without changing code or configuration-files as follows:
51
52 ```docker
53 mvn package
54 java -jar target/social-logout-0.0.1-SNAPSHOT.jar \
55   --spring.security.oauth2.client.registration.github.client-id=YOUR_GITHUB_APP_ID
56   --spring.security.oauth2.client.registration.github.client-secret=YOUR_GITHUB_APP_SECRET
57
58 ```
59
60 _If the app is running corectly, you should be able to Login/Logout via **`http://localhost:8080/`**_
61
62 The folks at Spring-Boot are keeping the guide and this repository up-to-date pretty well.
63 At the date of the writing of this article it is up to date with version [2.2.2.RELEASE](https://github.com/spring-guides/tut-spring-boot-oauth2/commit/274b864a2bcab5326979bc2ba370e32180510362 "Check out the exact version of this example-project, that is used in this article, if you want") of Spring-Boot.
64
65 _You may as well use any other OAuth2-application here. For example your own POC, if you already have build one that works while running on `localhost`_
66
67 ## Some Short Notes On OAuth2
68
69 I will only explain the protocol in very short words here, so that you can understand what goes wrong in case you stumble across one of the many pitfalls, when setting up oauth2.
70 You can [read more about oauth2 elswhere](https://www.oauth.com/oauth2-servers/getting-ready/ "And you most probably should: At least if you are planning to use it in production!")
71
72 For authentication, [oauth2](https://tools.ietf.org/html/rfc6749 "OAuth2 is a standardized protocol, that was implemented by several authorities and organizations") redirects the browser of your user to a server of your oauth2-provider.
73 This server authenticates the user and redirects the browser back to your server, providing additionally information and ressources, that lets your server know that the user was authenticated successfully and enables it to request more information in the name of the user.
74
75 Hence, when configuring oath2 one have to:
76
77 1. Provide the URI of the server of your oauth2-provider, the browser will be redirected to for authentication
78 1. Tell the server of the oauth2-provider the URL, the browser will be redirected to back after authentication
79 1. Also, your app has to provide some identification - a client-ID and -secret - when redirecting to the server of your oauth2-provider, which it has to know
80
81 There are a lot more things, which can be configured in oauth2, because the protocol is designed to fit a wide range of use-cases.
82 But in our case, it usually boils down to the parameters mentioned above.
83
84 Considering our combination of **`spring-security-oauth2`** with **GitHub** this means:
85
86 1. The redirect-URIs of well known oauth2-providers like GitHub are build into the library and do not have to be configured explicitly.
87 1. The URI, the provider has to redirect the browser back to after authenticating the user, is predefined by the library as well.  
88 _But as an additional security measure, almost every oauth2-provider requires you, to also specify this redirect-URI in the configuration on the side of the oauth2-provider._  
89
90    This is a good and necessary protection against fraud, but at the same time the primary source for missconfiguration:
91    **If the specified URI in the configuration of your app and on the server of your oauth2-provider does not match, ALL WILL FAIL!**
92 1. The ID and secret of the client (your GitHub-app) always have to be specified explicitly by hand.
93
94 Again, everything can be manually overriden, if needed.
95 Configuration-keys starting with **`spring.security.oauth2.client.registration.github`** are choosing GitHub as the oauth2-provider and trigger a bunch of predifined default-configuration.
96 If you have set up your own oauth2-provider, you have to configure everything manually.
97
98 ## Running The App Inside Docker
99
100 To faciliate the debugging - and because this most probably will be the way you are deploying your app anyway - we will start by building a docker-image from the app
101
102 For this, you do not have to change a single character in the example project - _all adjustments to the configuration will be done, when the image is started as a container_.
103 Just change to the subdirectory [`logout`](https://github.com/spring-guides/tut-spring-boot-oauth2/tree/master/logout "This is the subdirectory of the GitHub-Porject, that contains that step of the guide") of the checked out project and create the following `Dockerfile` there:
104
105 ```docker
106 FROM openjdk:8-jre-buster
107
108 COPY  target/social-logout-0.0.1-SNAPSHOT.jar /opt/app.jar
109 EXPOSE 8080
110 ENTRYPOINT [ "/usr/local/openjdk-8/bin/java", "-jar", "/opt/app.jar" ]
111 CMD []
112
113 ```
114
115 This defines a docker-image, that will run the app.
116
117 - The image deduces from **`openjdk:8-jre-buster`**, which is an installation of the latest [OpenJDK-JDK8](https://openjdk.java.net/projects/jdk8/) on a [Debian-Buster](https://www.debian.org/releases/stable/index.de.html "Have a look at the Release notes of that Debian-Version")
118 - The app will listen on port **`8080`**
119 - By default, a container instanciated from this image will automatically start the Java-app
120 - The **`CMD []`** overwrites the default from the parent-image with an empty list - _this enables us to pass command-line parameters to our spring-boot app which we will need to pass in our configuration_
121
122 You can build and tag this image with the following commands:
123
124 ```sh
125 mvn clean package
126 docker build -t juplo/social-logout:0.0.1 .
127
128 ```
129
130 This will tag your image as **`juplo/social-logout:0.0.1`** \- you obviously will/should use your own tag here, for example: `myfancytag`
131
132 _Do not miss out on the flyspeck ( `.`) at the end of the last line!_
133
134 You can run this new image with the follwing command - _and you should do that, to test that everything works as expected_:
135
136 ```sh
137 docker run \
138   --rm \
139   -p 8080:8080 \
140   juplo/social-logout:0.0.1 \
141   --spring.security.oauth2.client.registration.github.client-id=YOUR_GITHUB_ID \
142   --spring.security.oauth2.client.registration.github.client-secret=YOUR_GITHUB_SECRET
143
144 ```
145
146 - **`--rm`** removes this test-container automatically, once it is stopped again
147 - **`-p 8080:8080`** redirects port `8080` on `localhost` to the app
148
149 Everything _after_ the specification of the image (here: `juplo/social-logout:0.0.1`) is handed as a command-line parameter to the started Spring-Boot app - That is, why we needed to declare `CMD []` in our `Dockerfile`
150
151 We utilize this here to pass the ID and secret of your GitHub-app into the docker container -- just like when we started the JAR directly
152
153 The app should behave exactly the same now lik in the test above, where we started it directly by calling the JAR.
154
155 That means, that you should still be able to login into and logout of your app, if you browse to `http://localhost:8080` --
156 _At least, if you correctly configured `http://localhost:8080/login/oauth2/code/github` as authorization callback URL in the [settings of your OAuth App](https://github.com/settings/developers "If you have any problems here, you should check your settings: do not proceede, until this works!") on GitHub_.
157
158 ## Comming Next...
159
160 In the [next part](/how-to-redirect-to-spring-security-oauth2-behind-a-gateway-proxy-hiding-the-app-behind-a-reverse-proxy-gateway/ "Jump to the next part and read on...") of this series, we will hide the app behind a proxy and simulate that the setup is running on our real server **`example.com`**.