Formulir Login Keamanan Musim Semi

1. Perkenalan

Artikel ini akan fokus pada Login dengan Spring Security . Kita akan membuat di atas contoh Spring MVC sebelumnya yang sederhana, karena itu adalah bagian penting dari pengaturan aplikasi web bersama dengan mekanisme login.

2. Dependensi Maven

Saat bekerja dengan Spring Boot, starter spring-boot-starter-security secara otomatis akan menyertakan semua dependensi seperti spring-security-core , spring-security-web dan spring-security-config antara lain:

 org.springframework.boot spring-boot-starter-security 2.3.3.RELEASE 

Jika kami tidak menggunakan Spring Boot, silakan lihat artikel Spring Security with Maven, yang menjelaskan cara menambahkan semua dependensi yang diperlukan. Baik pegas-keamanan-web standar dan konfigurasi pegas-keamanan akan diperlukan.

3. Konfigurasi Java Keamanan Musim Semi

Mari kita mulai dengan membuat kelas konfigurasi Keamanan Musim Semi yang memperluas WebSecurityConfigurerAdapter.

Dengan menambahkan @EnableWebSecurity , kami mendapatkan dukungan integrasi Spring Security dan MVC:

@Configuration @EnableWebSecurity public class SecSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // authentication manager (see below) } @Override protected void configure(final HttpSecurity http) throws Exception { // http builder configurations for authorize requests and form login (see below) } }

Dalam contoh ini, kami telah menggunakan otentikasi dalam memori dan menetapkan 3 pengguna.

Selanjutnya, kita pergi melalui elemen yang telah kita gunakan untuk membuat konfigurasi login form.

Mari kita membangun Manajer Otentikasi kita terlebih dahulu.

3.1. Manajer Otentikasi

Penyedia Otentikasi didukung oleh implementasi dalam memori sederhana - InMemoryUserDetailsManager secara khusus. Ini berguna untuk pembuatan prototipe cepat ketika mekanisme persistensi penuh belum diperlukan:

protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER") .and() .withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER") .and() .withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN"); }

Di sini, kami mengkonfigurasi tiga pengguna dengan nama pengguna, kata sandi, dan peran yang di-hardcode.

Dimulai dengan Spring 5, kita juga harus menentukan encoder sandi . Dalam contoh kami, kami telah menggunakan BCryptPasswordEncoder:

@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

Selanjutnya, mari konfigurasikan HttpSecurity.

3.2. Konfigurasi untuk Mengotorisasi Permintaan

Kami mulai dengan melakukan konfigurasi yang diperlukan untuk Permintaan Otorisasi.

Di sini, kami mengizinkan akses anonim di / login sehingga pengguna dapat mengautentikasi. Membatasi / admin untuk peran ADMIN dan mengamankan yang lainnya:

@Override protected void configure(final HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() .antMatchers("/login*").permitAll() .anyRequest().authenticated() .and() // ... }

Perhatikan bahwa urutan elemen antMatchers () adalah signifikan - aturan yang lebih spesifik harus didahulukan, diikuti oleh yang lebih umum .

3.3. Konfigurasi untuk Form Login

Selanjutnya, kami memperluas konfigurasi di atas untuk form login dan logout:

@Override protected void configure(final HttpSecurity http) throws Exception { http // ... .and() .formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html", true) .failureUrl("/login.html?error=true") .failureHandler(authenticationFailureHandler()) .and() .logout() .logoutUrl("/perform_logout") .deleteCookies("JSESSIONID") .logoutSuccessHandler(logoutSuccessHandler()); }
  • loginPage () - halaman login kustom
  • loginProcessingUrl () - URL untuk memasukkan nama pengguna dan kata sandi
  • defaultSuccessUrl () - halaman arahan setelah login berhasil
  • failureUrl () - halaman arahan setelah login gagal
  • logoutUrl () - logout kustom

4. Tambahkan Spring Security ke Aplikasi Web

Untuk menggunakan konfigurasi Keamanan Musim Semi yang ditentukan di atas, kita perlu melampirkannya ke aplikasi web.

Kami akan menggunakan WebApplicationInitializer , jadi kami tidak perlu menyediakan web.xml:

public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SecSecurityConfig.class); sc.addListener(new ContextLoaderListener(root)); sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")) .addMappingForUrlPatterns(null, false, "/*"); } }

Perhatikan bahwa penginisialisasi ini tidak diperlukan jika kita menggunakan aplikasi Spring Boot. Lihat artikel kami tentang konfigurasi otomatis keamanan Spring Boot untuk detail selengkapnya tentang bagaimana konfigurasi keamanan dimuat di Spring Boot.

5. Konfigurasi XML Keamanan Musim Semi

Mari kita lihat juga konfigurasi XML yang sesuai.

Keseluruhan proyek menggunakan konfigurasi Java, jadi kita perlu mengimpor file konfigurasi XML melalui kelas Java @Configuration :

@Configuration @ImportResource({ "classpath:webSecurityConfig.xml" }) public class SecSecurityConfig { public SecSecurityConfig() { super(); } }

Dan Konfigurasi XML Keamanan Musim Semi - webSecurityConfig.xml :

6. web.xml

Sebelum pengenalan Spring 4 , kami menggunakan konfigurasi Spring Security di web.xml - hanya filter tambahan yang ditambahkan ke Spring MVC web.xml standar :

Spring Secured Application     springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy   springSecurityFilterChain /* 

Filter - DelegatingFilterProxy - hanya mendelegasikan ke kacang yang dikelola Spring - FilterChainProxy - yang dengan sendirinya dapat mengambil manfaat dari manajemen siklus hidup kacang Spring penuh dan semacamnya.

7. Formulir Login

Halaman formulir login akan didaftarkan dengan Spring MVC menggunakan mekanisme langsung untuk memetakan nama tampilan ke URL tanpa memerlukan pengontrol eksplisit di antaranya:

registry.addViewController("/login.html");

This, of course, corresponds to the login.jsp:


    
User:
Password:

The Spring Login form has the following relevant artifacts:

  • login – the URL where the form is POSTed to trigger the authentication process
  • username – the username
  • password – the password

8. Further Configuring Spring Login

We briefly discussed a few configurations of the login mechanism when we introduced the Spring Security Configuration above – let's go into some detail now.

One reason to override most of the defaults in Spring Security is to hide the fact that the application is secured with Spring Security and minimize the information a potential attacker knows about the application.

Fully configured, the login element looks like this:

@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html",true) .failureUrl("/login.html?error=true") }

Or the corresponding XML configuration:

8.1. The Login Page

Next, let's see how we can configure a custom login page using the loginPage() method:

http.formLogin() .loginPage("/login.html")

Or, via XML configuration:

login-page='/login.html'

If we don't specify this, Spring Security will generate a very basic Login Form at the /login URL.

8.2. The POST URL for Login

The default URL where the Spring Login will POST to trigger the authentication process is /login which used to be /j_spring_security_check before Spring Security 4.

We can use the loginProcessingUrl method to override this URL:

http.formLogin() .loginProcessingUrl("/perform_login")

Or, via XML configuration:

login-processing-url="/perform_login"

A good reason to override this default URL is to hide the fact that the application is actually secured with Spring Security – that information should not be available externally.

8.3. The Landing Page on Success

After a successful login process, the user is redirected to a page – which by default is the root of the web application.

We can override this via the defaultSuccessUrl() method:

http.formLogin() .defaultSuccessUrl("/homepage.html")

Or with XML configuration:

default-target-url="/homepage.html"

In case the always-use-default-target is set to true, then the user is always redirected to this page. If that attribute is set to false, then the user will be redirected to the previous page they wanted to visit before being prompted to authenticate.

8.4. The Landing Page on Failure

Same as with the Login Page, the Login Failure Page is autogenerated by Spring Security at /login?error by default.

To override this, we can use the failureUrl() method:

http.formLogin() .failureUrl("/login.html?error=true")

Or with XML:

authentication-failure-url="/login.html?error=true"

9. Conclusion

Dalam Contoh Masuk Musim Semi ini , kami mengonfigurasi proses otentikasi sederhana - kami membahas Formulir Masuk Keamanan Musim Semi, Konfigurasi Keamanan, dan beberapa penyesuaian lebih lanjut yang tersedia.

Implementasi tutorial Spring Login ini dapat ditemukan di proyek GitHub - ini adalah proyek berbasis Eclipse, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.

Ketika proyek berjalan secara lokal, contoh HTML dapat diakses di:

//localhost:8080/spring-security-mvc-login/login.html