1. Gambaran keseluruhan
Dalam tutorial ini, kita akan membincangkan cara melaksanakan SSO - Single Sign On - menggunakan Spring Security OAuth dan Spring Boot, menggunakan Keycloak sebagai Server Pengesahan.
Kami akan menggunakan 4 aplikasi berasingan:
- Pelayan Pengesahan - yang merupakan mekanisme pengesahan pusat
- Pelayan Sumber - penyedia Foo s
- Dua Aplikasi Pelanggan - aplikasi menggunakan SSO
Sederhananya, apabila pengguna cuba mengakses sumber melalui satu aplikasi Pelanggan, mereka akan diarahkan untuk mengesahkan terlebih dahulu, melalui Server Pengesahan. Keycloak akan menandatangani pengguna, dan semasa masih log masuk ke aplikasi pertama, jika aplikasi Pelanggan kedua diakses menggunakan penyemak imbas yang sama, pengguna tidak perlu memasukkan bukti kelayakan mereka lagi.
Kami akan menggunakan jenis pemberian Kod Pengesahan dari OAuth2 untuk mendorong pengesahan pengesahan.
Kami akan menggunakan timbunan OAuth di Spring Security 5. Sekiranya anda ingin menggunakan tumpukan legasi Spring Security OAuth, lihat artikel sebelumnya ini: Single Single Sign-On dengan Spring Security OAuth2 (tumpukan lama)
Seperti dalam panduan migrasi:
Spring Security merujuk kepada ciri ini sebagai Login OAuth 2.0 manakala Spring Security OAuth merujuknya sebagai SSO
Baiklah, mari kita masuk.
2. Pelayan Pengesahan
Sebelumnya, tumpukan Spring Security OAuth menawarkan kemungkinan menyiapkan Server Pengesahan sebagai Aplikasi Musim Semi.
Walau bagaimanapun, timbunan OAuth sudah tidak digunakan lagi oleh Spring dan sekarang kami akan menggunakan Keycloak sebagai Pelayan Pengesahan kami.
Oleh itu, kali ini, kami akan menetapkan Pelayan Pengesahan kami sebagai pelayan Keycloak tertanam dalam aplikasi Spring Boot .
Dalam pra-konfigurasi kami , kami akan menentukan dua pelanggan, ssoClient-1 dan ssoClient-2 , satu untuk setiap Aplikasi Pelanggan.
3. Pelayan Sumber
Seterusnya, kami memerlukan Server Sumber, atau API REST yang akan memberikan kami Foo s App Pelanggan kami akan makan.
Ini pada dasarnya sama seperti yang kami gunakan untuk Aplikasi Pelanggan Angular kami sebelum ini.
4. Permohonan Pelanggan
Sekarang mari kita lihat Aplikasi Pelanggan Thymeleaf kami; tentunya kita akan menggunakan Spring Boot untuk meminimumkan konfigurasi.
Perlu diingat bahawa kita perlu mempunyai 2 daripadanya untuk menunjukkan fungsi Single Sign-On .
4.1. Ketergantungan Maven
Pertama, kita memerlukan kebergantungan berikut dalam pom.xml kami :
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-oauth2-client org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf.extras thymeleaf-extras-springsecurity5 org.springframework spring-webflux io.projectreactor.netty reactor-netty
Untuk merangkumi semua sokongan pelanggan yang kami perlukan, termasuk keselamatan, kami hanya perlu menambahkan spring-boot-starter-oauth2-client . Juga, kerana RestTemplate lama tidak lagi digunakan, kami akan menggunakan WebClient , dan itulah sebabnya kami menambahkan spring-webflux dan reaktor-netty .
4.2. Konfigurasi Keselamatan
Seterusnya, bahagian yang paling penting, konfigurasi keselamatan aplikasi pelanggan pertama kami:
@EnableWebSecurity public class UiSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.antMatcher("/**") .authorizeRequests() .antMatchers("/") .permitAll() .anyRequest() .authenticated() .and() .oauth2Login(); } @Bean WebClient webClient(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, authorizedClientRepository); oauth2.setDefaultOAuth2AuthorizedClient(true); return WebClient.builder().apply(oauth2.oauth2Configuration()).build(); } }
Bahagian inti dari konfigurasi ini adalah kaedah oauth2Login () , yang digunakan untuk mengaktifkan sokongan Login OAuth 2.0 Spring Security. Oleh kerana kami menggunakan Keycloak, yang secara default adalah penyelesaian masuk tunggal untuk aplikasi web dan perkhidmatan web RESTful, kami tidak perlu menambahkan konfigurasi lebih lanjut untuk SSO.
Akhirnya, kami juga menentukan kacang WebClient untuk bertindak sebagai Klien HTTP sederhana untuk menangani permintaan yang akan dihantar ke Pelayan Sumber kami.
Dan inilah aplikasi.yml :
spring: security: oauth2: client: registration: custom: client-id: ssoClient-1 client-secret: ssoClientSecret-1 scope: read,write authorization-grant-type: authorization_code redirect-uri: //localhost:8082/ui-one/login/oauth2/code/custom provider: custom: authorization-uri: //localhost:8083/auth/realms/baeldung/protocol/openid-connect/auth token-uri: //localhost:8083/auth/realms/baeldung/protocol/openid-connect/token user-info-uri: //localhost:8083/auth/realms/baeldung/protocol/openid-connect/userinfo user-name-attribute: preferred_username thymeleaf: cache: false server: port: 8082 servlet: context-path: /ui-one resourceserver: api: project: url: //localhost:8081/sso-resource-server/api/foos/
Di sini, spring.security.oauth2.client.registration adalah ruang nama root untuk mendaftarkan pelanggan. Kami ditakrifkan pelanggan dengan id pendaftaran adat . Kemudian kami mendefinisikan id-klien , rahsia pelanggan , skopnya , jenis pemberian kebenaran dan uri-uri , yang tentunya harus sama dengan yang ditentukan untuk Pelayan Kebenaran kami.
Selepas itu, kami menentukan penyedia perkhidmatan kami atau Pelayan Pengesahan, sekali lagi dengan id kebiasaan yang sama , dan menyenaraikan URI yang berbeza untuk Spring Security untuk digunakan. Itu sahaja yang perlu kita tentukan, dan kerangka kerja melakukan keseluruhan proses log masuk, termasuk pengalihan ke Keycloak, dengan lancar untuk kita .
Perhatikan juga bahawa, dalam contoh kami di sini, kami melancarkan Pelayan Pengesahan kami, tetapi tentu saja kami juga dapat menggunakan penyedia pihak ketiga yang lain seperti Facebook atau GitHub.
4.3. Pengawal
Sekarang mari kita laksanakan pengawal kami di Aplikasi Pelanggan untuk meminta Foo dari Pelayan Sumber kami:
@Controller public class FooClientController { @Value("${resourceserver.api.url}") private String fooApiUrl; @Autowired private WebClient webClient; @GetMapping("/foos") public String getFoos(Model model) { List foos = this.webClient.get() .uri(fooApiUrl) .retrieve() .bodyToMono(new ParameterizedTypeReference
() { }) .block(); model.addAttribute("foos", foos); return "foos"; } }
As we can see, we have only one method here that'll dish out the resources to the foos template. We did not have to add any code for login.
4.4. Front End
Now, let's take a look at the front-end configuration of our client application. We're not going to focus on that here, mainly because we already covered in on the site.
Our client application here has a very simple front-end; here's the index.html:
Spring OAuth Client Thymeleaf - 1 Welcome !
Login
And the foos.html:
Spring OAuth Client Thymeleaf -1 Hi, preferred_username
ID
Name
No foos
ID
Name
The foos.html page needs the users to be authenticated. If a non-authenticated user tries to access foos.html, they'll be redirected to Keycloak's login page first.
4.5. The Second Client Application
We'll configure a second application, Spring OAuth Client Thymeleaf -2 using another client_idssoClient-2.
It'll mostly be the same as the first application we just described.
The application.yml will differ to include a different client_id, client_secret and redirect_uri in its spring.security.oauth2.client.registration:
spring: security: oauth2: client: registration: custom: client-id: ssoClient-2 client-secret: ssoClientSecret-2 scope: read,write authorization-grant-type: authorization_code redirect-uri: //localhost:8084/ui-two/login/oauth2/code/custom
And, of course, we need to have a different server port for it as well, so that we can run them in parallel:
server: port: 8084 servlet: context-path: /ui-two
Finally, we'll tweak the front end HTMLs to have a title as Spring OAuth Client Thymeleaf – 2 instead of – 1 so that we can distinguish between the two.
5. Testing SSO Behavior
To test SSO behavior, let's run our Applications.
We'll need all our 4 Boot Apps – the Authorization Server, the Resource Server and both Client Applications – to be up and running for this.
Now let's open up a browser, say Chrome, and log in to Client-1 using the credentials [email protected]/123. Next, in another window or tab, hit the URL for Client-2. On clicking the login button, we'll be redirected to the Foos page straightaway, bypassing the authentication step.
Similarly, if the user logs in to Client-2 first, they need not enter their username/password for Client-1.
6. Conclusion
Dalam tutorial ini, kami memberi tumpuan untuk melaksanakan Single Sign-On menggunakan Spring Security OAuth2 dan Spring Boot menggunakan Keycloak sebagai penyedia identiti.
Seperti biasa, kod sumber penuh boleh didapati di GitHub.