本指南将引导您完成建立一个资源由Spring Security的保护的一个简单的Web应用程序的过程。java
你将构建一个经过固定的用户列表做为后端的登陆表单来保护页面安全的Spring MVC应用程序git
大约15分钟github
一个喜欢的文本编辑器或IDEweb
JDK 1.8 或更高版本spring
Gradle 2.3+ 或 Maven 3.0+数据库
你一样能够将本指南的代码直接导入Spring Tool Suite (STS)并从这里开始你的工做segmentfault
如同大多数的Spring入门指南,你能够从头开始并完成每个步骤,或者能够跳过这个你已经熟悉的基本配置过程。不管哪一种方式,您最终会得到可运行的代码。后端
要从头开始,请看“使用gradle构建”部分。浏览器
要跳过最基本的部分,按下面的步骤操做:
下载而后解压本项目的代码,或者使用Git克隆一个代码仓库:
git clone https://github.com/spring-guides/gs-securing-web.git
cd 到 gs-securing-web/initial 目录
直接跳到“部署Spring Security”
首先,你要建立一个基本的构建脚本。你可使用任何你喜欢的构建系统来构建Spring应用程序,可是你所须要的Gralde和Maven构建代码已经包含在这里了。若是你对二者都不熟悉,能够参考“使用Gradle构建Java项目”或“使用Maven构建Java项目”。
你须要在你选的一个用做项目目录的文件夹中,建立下面的子目录结构;例如你能够在*nix系统中使用mkdir -p src/main/java/hello
这样的命令来完成。
└── src └── main └── java └── hello
下面是initial目录下的Gradle的build文件(译注:实际这个initial指的是项目的根目录,它包含了上面所建立的src目录,以及gradle.build文件,这样执行gradle build
命令时,gradle才能正确地找到要构建的代码)。
文件名:build.gradle
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'spring-boot' jar { baseName = 'gs-securing-web' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { compile("org.springframework.boot:spring-boot-starter-thymeleaf") testCompile("junit:junit") } task wrapper(type: Wrapper) { gradleVersion = '2.3' }
略,请参考原文
略,请参考原文
在你能够尝试将安全性应用于Web应用以前,你须要一个用于“保护”的Web应用程序。本节中的步骤指导您完成建立一个很是简单的Web应用程序。而后你将在下一节使用Spring Security将其保护起来。
这个web应用程序包括两个简单的视图,一个是“主页”,一个是“Hello World”页。“主页”的视图由下面这个themeleaf模板来定义:
文件名:src/main/resources/templates/home.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Example</title> </head> <body> <h1>Welcome!</h1> <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p> </body> </html>
如你所见,这个简单的视图包括一个指向“/hello”页面的连接,它由下面这个themeleaf模板来定义:
src/main/resources/templates/hello.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Hello World!</title> </head> <body> <h1>Hello world!</h1> </body> </html>
这个Web应用基于Spring MVC,所以你须要配置Spring MVC,而后设置view controller来暴露这些模板。下面就是一个配置好Spring MVC的Class。
文件名:src/main/java/hello/MvcConfig.java
package hello; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/home").setViewName("home"); registry.addViewController("/").setViewName("home"); registry.addViewController("/hello").setViewName("hello"); registry.addViewController("/login").setViewName("login"); } }
addViewControllers()
方法(覆盖了WebMvcConfigurerAdapter
的同名方法)添加了四个view controller。其中两个view controller指向了“home”视图(在home.html
中定义),另外一个指向了“hello”视图(在hello.html
中定义)。第四个view controller指向另外一个视图“login”,你将会在下个章节建立这个视图。
此刻,你能够直接跳到“让Web应用可执行”的部分,在不须要任何登录工做的状况下运行Web应用。
一旦最基本的Web应用建立好了,你能够给他加上安全防御。
假设如今你但愿防止未受权的用户在输入“/hello”这个网址后看到欢迎页的内容。当前状态下,若是用户点击“home”页上的连接,他们能够没有任何阻碍地看到欢迎页。如今你须要在用户看到这个页面前添加一个强制用户登陆的阻碍。
你能够经过配置Spring Security来完成上面所说的事。若是Spring Security在classpath中,SpringBoot会自动使用“基本”HTTP认证来保护全部HTTP端点,你也能够进一步的定制安全设置。首先要作的事情就是把Spring Security加入到classpath中。
若是使用Gradle,它将会是dependencies
部分中的一行:
文件名:build.gradle
dependencies { ... compile("org.springframework.boot:spring-boot-starter-security") ... }
若是使用Maven,他将会是<dependencies>
标签中的一个子标签:
文件名:pom.xml
<dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ... </dependencies>
下面是确保只有认证过的用户才能看到“秘密的”欢迎页的安全配置:
文件名:src/main/java/hello/WebSecurityConfig.java
package hello; 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.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } }
这个WebSecurityConfig
类被@EnableWebMvcSecurity
标注,来启用Spring Security的web安全支持、以及提供与Spring MVC的融合。这个类还继承了WebSecurityConfigurerAdapter
并重写了一些方法来指定一些特定的Web安全设置。
configure(HttpSecurity)
方法规定了哪一个URL应该被保护,哪一个不该该。具体而言,“/”和“/home”的路径被配置为不须要任何认证。全部其余URL必须进行身份验证。
当用户成功登陆后,他们将被重定向到先前请求的须要身份验证的页面。还有一个自定义(由loginPage()
指定)的“/login”页面,每一个用户均可以查看。
对于configureGlobal(AuthenticationManagerBuilder)
方法,它设置了一个单一用户在内存中的用户数据库。该用户被赋予“user”的用户名,“password”的密码,以及“USER”做为角色。
如今,咱们须要建立登陆页面。目前已经为“login”视图赋予了视图控制器,因此你只须要建立login视图自己:
文件名:src/main/resources/templates/login.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Example </title> </head> <body> <div th:if="${param.error}"> Invalid username and password. </div> <div th:if="${param.logout}"> You have been logged out. </div> <form th:action="@{/login}" method="post"> <div><label> User Name : <input type="text" name="username"/> </label></div> <div><label> Password: <input type="password" name="password"/> </label></div> <div><input type="submit" value="Sign In"/></div> </form> </body> </html>
正如你所看到的,这个Thymeleaf模板只是给出了一个采集用户名和密码,并将它们做为请求post到“/login”的表单。正如刚刚配置的,Spring Security提供一个过滤器,截取该请求,并验证用户身份。若是用户身份验证失败,页面被重定向到“/login?error”,咱们的页面将显示相应的错误信息。一旦成功登出了,咱们的应用程序重定向到到“/login?logout”并显示相应的登录成功的消息。
最后,咱们须要给用户提供一种方式来显示当前用户名和“Sign Out”按钮。更新hello.html
来问好当前用户,并包含一个“Sign Out”的按钮,以下所示:
文件名:src/main/resources/templates/hello.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Hello World!</title> </head> <body> <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> <form th:action="@{/logout}" method="post"> <input type="submit" value="Sign Out"/> </form> </body> </html>
咱们经过使用Spring Security所集成的HttpServletRequest#getRemoteUser()
来显示用户名。该“Sign Out”按钮提交一个POST请求给“/logout”。一旦成功退出,将用户重定向到“/login?logout”。
虽然能够打包这项服务做为一个传统的web应用程序归档或WAR文件部署到外部应用服务器,下面展现了更简单的方法来建立一个独立的应用程序。你将打包一切到一个单一的,可执行的JAR文件中,用一个良好旧式Javamain()
方法来调用。在此过程当中,你会用到Spring所支持的嵌入式Tomcat servlet容器做为HTTP运行实例,而不是部署一个外部实例。
文件名:src/main/java/hello/Application.java
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) throws Throwable { SpringApplication.run(Application.class, args); } }
@SpringBootApplication
是个方便的注解,自动添加了全部如下内容:
@Configuration
标记这个类做为bean以定义应用程序上下文的来源。
@EnableAutoConfiguration
告诉SpringBoot开始添加基于classpath设置,其余Beans,以及各类属性设置的Beans。
一般状况下你会给Spring MVC应用加上@EnableWebMvc
注解,但当Spring Boot看到classpath中有spring-webmvc时,会自动添加这个注解。这标记该应用程序是一个Web应用程序,并激活一些关键行为,好比建立一个DispatcherServlet
。
@ComponentScan
告诉Spring去hello
包中寻找其余组件,配置,服务。
该main()
方法使用Spring Boot的SpringApplication.run()
方法来启动应用程序。你有没有注意到,这里没有一行XML,一样也没有web.xml文件。这个Web应用程序是100%纯Java写的,你没必要处理配置任何管道或基础设施(译注:plumbing or infrastructure,我这里直译了)。
若是你正在使用gradle,你可使用./gradlew bootRun
命令来运行应用程序。
你能够构建一个包含全部必要的依赖,类和资源的一个可执行的JAR文件。这样使传输,版本管理和部署服务在整个开发生命周期在不一样的环境,等等,变得更容易
./gradlew build
而后你能够这样运行JAR包:
java -jar build/libs/gs-securing-web-0.1.0.jar
若是你正在使用Maven,你能够经过mvn spring-boot:run
来运行应用,或者你也能够经过mvn clean package
来构建JAR包,而后输入下面的命令来运行:
java -jar target/gs-securing-web-0.1.0.jar
注意:上述过程将建立一个可运行的JAR。你也能够选择构建一个经典的WAR包来代替。
一旦应用程序启动,用浏览器访问http://localhost:8080。你应该看到主页:
当你点击这个连接,它会尝试把你带到/hello
所指向的欢迎页,但由于这个页面是受保护的,并且目前为止你没有登陆,它会带你到登录页
注意:若是你是直接从“不安全”的版本跳到这的,那么你将不会看到登录页,请放松地回到上面写完其他的基于安全的代码
在登陆页面,分别输入“user”和“password”做为用户名和密码,便可做为测试用户登陆。一旦你提交登陆表单,你会被进行身份验证,而后带你到欢迎页:
若是你点击“Sign Out”按钮,你的身份验证被撤销,你将会返回到登陆页并显示一个消息提示你已经登出。
恭喜你,你已经开发了一个简单的、使用Spring Security来保护的Web应用。
想写一个新的指南,或向已有的指南贡献本身的能力?请看咱们的贡献指南