Spring Security 5 登录表单示例

Spring Security 5 登录表单示例

原文: 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

<properties>
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<spring.version>5.2.0.RELEASE</spring.version>
</properties>	

<!-- Spring MVC Dependency -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>${spring.version}</version>
</dependency>

<!-- Spring Security Core -->
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-core</artifactId>
	<version>${spring.version}</version>
</dependency>

<!-- Spring Security Config -->
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-config</artifactId>
	<version>${spring.version}</version>
</dependency>

<!-- Spring Security Web -->
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-web</artifactId>
	<version>${spring.version}</version>
</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

package com.howtodoinjava.demo.spring.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	PasswordEncoder passwordEncoder;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication()
		.passwordEncoder(passwordEncoder)
		.withUser("user").password(passwordEncoder.encode("123456")).roles("USER")
		.and()
		.withUser("admin").password(passwordEncoder.encode("123456")).roles("USER", "ADMIN");
	}

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

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
		.antMatchers("/login")
			.permitAll()
		.antMatchers("/**")
			.hasAnyRole("ADMIN", "USER")
		.and()
			.formLogin()
			.loginPage("/login")
			.defaultSuccessUrl("/home")
			.failureUrl("/login?error=true")
			.permitAll()
		.and()
			.logout()
			.logoutSuccessUrl("/login?logout=true")
			.invalidateHttpSession(true)
			.permitAll()
		.and()
			.csrf()
			.disable();
	}
}

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

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

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

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

SpringSecurityInitializer.java

package com.howtodoinjava.demo.spring.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
	//no code needed
}

另外,包括SecurityConfigAppInitializer

AppInitializer.java

package com.howtodoinjava.demo.spring.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] { HibernateConfig.class, SecurityConfig.class };
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebMvcConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}

3. 添加自定义登录表单

3.1. LoginController

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

LoginController.java

package com.howtodoinjava.demo.spring.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class LoginController 
{
	@RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(@RequestParam(value = "error", required = false) String error, 
    						@RequestParam(value = "logout", required = false) String logout,
    						Model model) {
		String errorMessge = null;
		if(error != null) {
			errorMessge = "Username or Password is incorrect !!";
		}
		if(logout != null) {
			errorMessge = "You have been successfully logged out !!";
		}
		model.addAttribute("errorMessge", errorMessge);
        return "login";
    }

    @RequestMapping(value="/logout", method = RequestMethod.GET)
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){    
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/login?logout=true";
    }
}

3.2. login.jsp

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

login.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body onload='document.loginForm.username.focus();'>
	<h1>Spring Security 5 - Login Form</h1>

	<c:if test="${not empty errorMessge}"><div style="color:red; font-weight: bold; margin: 30px 0px;">${errorMessge}</div></c:if>

	<form name='login' action="/login" method='POST'>
		<table>
			<tr>
				<td>UserName:</td>
				<td><input type='text' name='username' value=''></td>
			</tr>
			<tr>
				<td>Password:</td>
				<td><input type='password' name='password' /></td>
			</tr>
			<tr>
				<td colspan='2'><input name="submit" type="submit" value="submit" /></td>
			</tr>
		</table>
		<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
	</form>
</body>
</html>

4. Spring Security 5 登录表单演示

  1. 用 maven 运行命令tomcat7:run启动应用程序。启动主页http://localhost:8080/home。它将重定向到登录页面http://localhost:8080/login

    Login Form

    登录表单

  2. 输入不正确的用户名或密码。 将显示登录错误消息。

    Incorrect username or password

    不正确的用户名或密码

  3. 输入正确的用户名和密码组合。user123456。将显示主页。

    Home Page

    主页

  4. 单击注销按钮。 用户将被注销,然后重定向回到登录页面。

    Logged Out

    注销

学习愉快!

下载源码