原文: https://howtodoinjava.com/spring5/security5/login-form-example/

在此 Spring Security 5 教程中,学习将基于的自定义登录表单的安全性添加到我们的 Spring WebMVC 应用程序中。 我正在使用 Spring Security 5 构建此示例。 本教程还讨论了从会话注销。

1. 包含 Spring Security 5 依赖项

包括 SpringSecurity 包。 我正在使用 maven,因此为 spring security version 5.0.7.RELEASE 添加了相应的依赖项。

pom.xml

  1. <properties>
  2. <failOnMissingWebXml>false</failOnMissingWebXml>
  3. <spring.version>5.2.0.RELEASE</spring.version>
  4. </properties>
  5. <!-- Spring MVC Dependency -->
  6. <dependency>
  7. <groupId>org.springframework</groupId>
  8. <artifactId>spring-webmvc</artifactId>
  9. <version>${spring.version}</version>
  10. </dependency>
  11. <!-- Spring Security Core -->
  12. <dependency>
  13. <groupId>org.springframework.security</groupId>
  14. <artifactId>spring-security-core</artifactId>
  15. <version>${spring.version}</version>
  16. </dependency>
  17. <!-- Spring Security Config -->
  18. <dependency>
  19. <groupId>org.springframework.security</groupId>
  20. <artifactId>spring-security-config</artifactId>
  21. <version>${spring.version}</version>
  22. </dependency>
  23. <!-- Spring Security Web -->
  24. <dependency>
  25. <groupId>org.springframework.security</groupId>
  26. <artifactId>spring-security-web</artifactId>
  27. <version>${spring.version}</version>
  28. </dependency>

2. 创建 Spring Security 配置

2.1. 配置身份验证和 URL 安全

  • 我创建了这个简单的安全配置,并添加了两个演示用户useradmin
  • @EnableWebSecurity启用 Spring Security 的网络安全支持,并提供 Spring MVC 集成。
  • WebSecurityConfigurerAdapter提供了一组用于启用特定 Web 安全配置的方法。
  • configure(HttpSecurity http)用于保护需要安全性的不同 URL。
  • 在 URL /login上配置自定义登录页面。 如果用户名/密码匹配,则将请求重定向到/home,否则登录页面会刷新并显示相应的错误消息。
  • 它还配置从会话注销。 注销后,用户将再次重定向到登录页面。

我已使用auth.inMemoryAuthentication()使用内存中身份验证。 您可以使用auth.jdbcAuthentication()配置 JDBC 身份验证,或使用auth.ldapAuthentication()配置 LDAP 身份验证。

SecurityConfig.java

  1. package com.howtodoinjava.demo.spring.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  6. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.security.crypto.password.PasswordEncoder;
  10. @EnableWebSecurity
  11. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  12. @Autowired
  13. PasswordEncoder passwordEncoder;
  14. @Override
  15. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  16. auth.inMemoryAuthentication()
  17. .passwordEncoder(passwordEncoder)
  18. .withUser("user").password(passwordEncoder.encode("123456")).roles("USER")
  19. .and()
  20. .withUser("admin").password(passwordEncoder.encode("123456")).roles("USER", "ADMIN");
  21. }
  22. @Bean
  23. public PasswordEncoder passwordEncoder() {
  24. return new BCryptPasswordEncoder();
  25. }
  26. @Override
  27. protected void configure(HttpSecurity http) throws Exception {
  28. http.authorizeRequests()
  29. .antMatchers("/login")
  30. .permitAll()
  31. .antMatchers("/**")
  32. .hasAnyRole("ADMIN", "USER")
  33. .and()
  34. .formLogin()
  35. .loginPage("/login")
  36. .defaultSuccessUrl("/home")
  37. .failureUrl("/login?error=true")
  38. .permitAll()
  39. .and()
  40. .logout()
  41. .logoutSuccessUrl("/login?logout=true")
  42. .invalidateHttpSession(true)
  43. .permitAll()
  44. .and()
  45. .csrf()
  46. .disable();
  47. }
  48. }

了解更多:登录表单的 Spring Security XML Config

2.2. 将 Spring Security 绑定到 Web 应用程序

在 Spring Web 应用程序中,使用DelegatingFilterProxy实现安全性。 要使用 Java 配置的 spring 容器注册它,您应该使用AbstractSecurityWebApplicationInitializer

Spring 将在应用程序启动期间检测到此类的实例,并在其他已注册过滤器之前注册DelegatingFilterProxy以使用springSecurityFilterChain。 它还注册了ContextLoaderListener

SpringSecurityInitializer.java

  1. package com.howtodoinjava.demo.spring.config;
  2. import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
  3. public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
  4. //no code needed
  5. }

另外,包括SecurityConfigAppInitializer

AppInitializer.java

  1. package com.howtodoinjava.demo.spring.config;
  2. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  3. public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  4. @Override
  5. protected Class<?>[] getRootConfigClasses() {
  6. return new Class[] { HibernateConfig.class, SecurityConfig.class };
  7. }
  8. @Override
  9. protected Class<?>[] getServletConfigClasses() {
  10. return new Class[] { WebMvcConfig.class };
  11. }
  12. @Override
  13. protected String[] getServletMappings() {
  14. return new String[] { "/" };
  15. }
  16. }

3. 添加自定义登录表单

3.1. LoginController

添加登录控制器方法来处理登录和注销请求。

LoginController.java

  1. package com.howtodoinjava.demo.spring.controller;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.security.core.Authentication;
  5. import org.springframework.security.core.context.SecurityContextHolder;
  6. import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.ui.Model;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import org.springframework.web.bind.annotation.RequestMethod;
  11. import org.springframework.web.bind.annotation.RequestParam;
  12. @Controller
  13. public class LoginController
  14. {
  15. @RequestMapping(value = "/login", method = RequestMethod.GET)
  16. public String loginPage(@RequestParam(value = "error", required = false) String error,
  17. @RequestParam(value = "logout", required = false) String logout,
  18. Model model) {
  19. String errorMessge = null;
  20. if(error != null) {
  21. errorMessge = "Username or Password is incorrect !!";
  22. }
  23. if(logout != null) {
  24. errorMessge = "You have been successfully logged out !!";
  25. }
  26. model.addAttribute("errorMessge", errorMessge);
  27. return "login";
  28. }
  29. @RequestMapping(value="/logout", method = RequestMethod.GET)
  30. public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
  31. Authentication auth = SecurityContextHolder.getContext().getAuthentication();
  32. if (auth != null){
  33. new SecurityContextLogoutHandler().logout(request, response, auth);
  34. }
  35. return "redirect:/login?logout=true";
  36. }
  37. }

3.2. login.jsp

创建将接受usernamepasswordlogin.jsp文件; 并将它们发布到 URL /login

login.jsp

  1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  2. <html>
  3. <body onload='document.loginForm.username.focus();'>
  4. <h1>Spring Security 5 - Login Form</h1>
  5. <c:if test="${not empty errorMessge}"><div style="color:red; font-weight: bold; margin: 30px 0px;">${errorMessge}</div></c:if>
  6. <form name='login' action="/login" method='POST'>
  7. <table>
  8. <tr>
  9. <td>UserName:</td>
  10. <td><input type='text' name='username' value=''></td>
  11. </tr>
  12. <tr>
  13. <td>Password:</td>
  14. <td><input type='password' name='password' /></td>
  15. </tr>
  16. <tr>
  17. <td colspan='2'><input name="submit" type="submit" value="submit" /></td>
  18. </tr>
  19. </table>
  20. <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
  21. </form>
  22. </body>
  23. </html>

4. Spring Security 5 登录表单演示

  1. 用 maven 运行命令tomcat7:run启动应用程序。启动主页http://localhost:8080/home。它将重定向到登录页面http://localhost:8080/login
    Spring Security 5 登录表单示例 - 图1
    登录表单

  2. 输入不正确的用户名或密码。 将显示登录错误消息。
    Spring Security 5 登录表单示例 - 图2
    不正确的用户名或密码

  3. 输入正确的用户名和密码组合。user123456。将显示主页。
    Spring Security 5 登录表单示例 - 图3
    主页

  4. 单击注销按钮。 用户将被注销,然后重定向回到登录页面。
    Spring Security 5 登录表单示例 - 图4
    注销

学习愉快!

下载源码