今天我们将了解Spring安全登录示例. 在阅读这篇文章之前,请先浏览一下我在spring4security简介;得到一些基本知识。
Spring Security登录注销示例
在这篇文章中,我们将发展Spring4MVC安全Web应用程序通过使用内存选项提供登录和注销功能。这个例子使用Spring Javaconfig和Spring注解,这意味着不使用web.xml文件和springxml配置(旧式)。
如果您不熟悉Spring3.x安全模块,请先浏览下面的帖子,尝尝SpringSecurity的诀窍。
- 使用内存、UserDetailsService和JDBC身份验证的Spring Mvc安全示例
- 使用DAO、JDBC、内存认证的Servlet Web应用程序中的Spring安全性
Spring 4安全模块支持以下选项来存储和管理用户凭据:
- 内存存储
- 关系数据库(RDBMS)
- 没有SQL数据存储
- LDAP
在本例中,我们将使用“;内存存储”;选项。我们将在接下来的帖子中讨论其他选择。
我们将使用spring4.0.2.RELEASE、springsts3.7suiteide、springtcserver3.1withjava1.8和Maven构建工具来开发这个示例。
Spring安全登录示例
我们将使用spring4的安全特性开发一个登录和注销逻辑。此应用程序的主要目的是在不使用“;的情况下开发应用程序;web.xml和#8221,而且不需要编写一行springxmlbeans配置。这意味着我们将在Spring注解中使用Spring Javaconfig特性。
我们将开发具有以下功能的应用程序:
- 欢迎页面
- 登录页面
- 主页
- 注销功能
请使用以下步骤来开发和研究这个spring4安全简单登录示例。
- 使用以下详细信息在springsts套件中创建一个简单的springwebmaven”;项目
Project Name : SpringMVCSecruityMavenApp
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>SpringMVCSecruityMavenApp</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<java.version>1.8</java.version>
<spring.version>4.0.2.RELEASE</spring.version>
<spring.security.version>4.0.2.RELEASE</spring.security.version>
<servlet.api.version>3.1.0</servlet.api.version>
<jsp.api.version>2.2</jsp.api.version>
<jstl.version>1.2</jstl.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.api.version}</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMVCSecruityMavenApp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
注:-如果您不知道&&8220;<;failOnMissingWebXml>;&&8221;标志,请阅读本文结尾部分,以便更好地理解此元素的用法。
登录控制器.java
package com.journaldev.spring.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController {
@RequestMapping(value = { "/"}, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.setViewName("welcomePage");
return model;
}
@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
public ModelAndView homePage() {
ModelAndView model = new ModelAndView();
model.setViewName("homePage");
return model;
}
@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid Credentials provided.");
}
if (logout != null) {
model.addObject("message", "Logged out from JournalDEV successfully.");
}
model.setViewName("loginPage");
return model;
}
}
代码Ex夷平面:-我们在“;LoginController”;中定义了三个方法来处理三种不同类型的客户端请求
- welcomePage()将处理使用“;/”;URI的所有客户端请求。
- homePage()将处理所有使用“;/homePage”;URI的客户端请求。
- loginPage()将处理所有使用&8220;/loginPage&8221;URI的客户端请求。
- 在loginPage()中,我们负责处理错误和注销消息。
登录安全配置.java
package com.journaldev.spring.secuity.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
authenticationMgr.inMemoryAuthentication()
.withUser("journaldev")
.password("jd@123")
.authorities("ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/homePage").access("hasRole("ROLE_USER")")
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
}
代码Ex夷平面:-我们在“;LoginSecurityConfig”;中定义了两个方法来存储和管理用户凭据,并负责登录和注销安全功能。
- @EnableWebSecurity注解用于在任何web应用程序中启用web安全性。
- @EnableWebMVCSecurity注解用于在基于SpringMVC的web应用程序中启用web安全性。
- “;LoginSecurityConfig”;类或任何指定用于配置Spring Security的类,都应扩展“;websecurityconfiguratoradapter”;类或实现相关接口。
- configureGlobal()方法用于存储和管理用户凭据。
- 在configureGlobal()方法中,我们可以使用authorities()方法来定义我们的应用程序角色,例如“;ROLE#USER”;。我们也可以使用roles()方法来达到同样的目的。
- authorities()和roles()方法之间的区别:
authorities()需要一个完整的角色名,如“;roleŠUSER”;&;角色需要一个类似的角色;。它将自动将“;角色”;值添加到此“;用户”;角色名称。
注:-在我接下来的文章中,我们将开发另一个示例来演示“;用户”;,”;管理员”。
- 处理登录和注销安全性的重要方法是configure(HttpSecurity http)
- 下面截取的代码用于避免未经授权访问&8220;/homePage&8221;。如果您尝试直接访问此页,我们将自动重定向到“;/login页”;页。
- 我们使用formLogin()和logout()方法配置了登录和注销功能。
注:-@EnableWebSecurity=@EnableWebMVCSecurity+额外功能。这就是为什么在Spring4.x框架中不推荐使用@EnableWebMVCSecurity注解。
.antMatchers("/homePage").access("hasRole("ROLE_USER")")
如果我们移除访问(“;hasRole(‘;角色#用户’;)”;)方法调用,则无需登录应用程序即可访问此页面。
瞧ginApplicationConfig.java应用程序配置
package com.journaldev.spring.secuity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.journaldev.spring.*" })
@Import(value = { LoginSecurityConfig.class })
public class LoginApplicationConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
代码Ex夷平面:-我们使用“;LoginApplicationConfig”;类来定义Spring Mvc视图解析器,以避免编写“;web.xml和#8221;文件。
- @EnableWebMvc注解用于在Spring框架中启用SpringWebMVC应用程序特性
- @Import注解用于将Spring安全配置类导入到这个类中。
- @ComponentScan注解用于在指定的包中执行组件扫描。等于“;<;上下文:组件扫描;在springxml配置中。
package com.journaldev.spring.secuity.config.core;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
“;SpringSecurityInitializer”;用于注册DelegatingFilterProxy to use the springSecurityFilterChain. It avoids writing Filters configuration in web.xml file.
“;SpringMVCWebAppInitializer”;类用于初始化不带web.xml文件基于注解的配置中的文件。
SpringMVCWebAppInitializer.java
package com.journaldev.spring.secuity.config.core;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.journaldev.spring.secuity.config.LoginApplicationConfig;
public class SpringMVCWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { LoginApplicationConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
注:-
- 当我们访问应用程序时,默认情况下SpringMVCWebAppInitializer’;的getServletMappings()将允许访问根url:“;/”;。我们可以重写以转发到其他URL。
- Spring或Pivotal团队正在解决这个问题,通过引入注解来避免这么多Java代码。请在https://jira.spring.io/browse/SPR-10359。
<h3>Welcome to JournalDEV Tutorials</h3>
<a href="${pageContext.request.contextPath}/loginPage">Login to Journal</a>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<html>
<body onload="document.loginForm.username.focus();">
<h3>JournalDEV Tutorials</h3>
<c:if test="${not empty error}"><div>${error}</div></c:if>
<c:if test="${not empty message}"><div>${message}</div></c:if>
<form name="login" action="<c:url value="/loginPage" />" 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>
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<ul>
<li>Java 8 tutorial</li>
<li>Spring tutorial</li>
<li>Gradle tutorial</li>
<li>BigData tutorial</li>
</ul>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById("logout").submit()">Logout</a>
</c:if>
运行Spring Security MVC登录注销示例
要运行这个springweb应用程序,我们需要任何支持spring4和java8环境的Web容器和servlet3.1.0容器。
- 在springsts套件中的springtc服务器上部署和运行
- 它会自动访问我们的应用程序欢迎页面url,如下所示。
- 单击“;登录到JournalDEV”;链接访问登录页面。
- 现在,请提供错误的登录详细信息并单击“;登录”;按钮。
- 现在,请提供在“;LoginSecurityConfig”;类中配置的正确登录详细信息。
- 单击“;注销”;链接从应用程序注销。
在这里,我们可以看到以下错误消息:&&8220;提供的凭据无效。&&8221;
成功登录到我们的应用程序后,我们可以看到我们的应用程序主页与“;注销”;链接。
我们可以再次从这里看到我们的应用程序被重新引导出登录页面。
在这个页面中我们可以观察到一些登录成功的消息。
注:-如果我们观察这个例子,我们没有使用web.xml文件文件正确。由于它是一个Web应用程序,Maven搜索web.xml文件如果在应用程序中找不到,则会引发一些错误。为了避免与Maven相关的问题,我们需要在pom.xml文件文件。
这就是Spring4安全模块的全部简单例子。我们将在我即将发表的文章中开发一些更实时有用的示例,如管理角色、RememberMe特性、WebSocket安全性等等。
如果你喜欢我的帖子或有任何问题/建议,请给我留言。