一 点睛
我们在编写Web应用时,经常需要对页面做一些安全控制,比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop、拦截器实现,也可以通过框架实现(如:Apache Shiro、Spring Security)。
本篇将具体介绍在Spring Boot中如何使用Spring Security进行安全控制。
二 实战
1 引入相关依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 1<dependencies>
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter</artifactId>
5 </dependency>
6 <dependency>
7 <groupId>org.springframework.boot</groupId>
8 <artifactId>spring-boot-starter-test</artifactId>
9 <scope>test</scope>
10 </dependency>
11
12 <dependency>
13 <groupId>org.springframework.boot</groupId>
14 <artifactId>spring-boot-starter-web</artifactId>
15 </dependency>
16
17 <dependency>
18 <groupId>org.springframework.boot</groupId>
19 <artifactId>spring-boot-starter-thymeleaf</artifactId>
20 </dependency>
21 <!--引入security-->
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-security</artifactId>
25 </dependency>
26</dependencies>
27
2 新建控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 1package com.didispace.web;
2
3import org.springframework.stereotype.Controller;
4import org.springframework.ui.ModelMap;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RequestMethod;
7
8
9@Controller
10public class HelloController {
11
12 @RequestMapping("/")
13 public String index() {
14 return "index";
15 }
16
17 @RequestMapping("/hello")
18 public String hello() {
19 return "hello";
20 }
21
22 @RequestMapping(value = "/login", method = RequestMethod.GET)
23 public String login() {
24 return "login";
25 }
26
27}
28
3 安全配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 1package com.didispace;
2
3import org.springframework.beans.factory.annotation.Autowired;
4import org.springframework.context.annotation.Configuration;
5import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
6import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
8import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
9
10@Configuration
11//通过@EnableWebSecurity注解开启Spring Security的功能
12@EnableWebSecurity
13//必须继承WebSecurityConfigurerAdapter
14public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
15
16 @Override
17 //重写该方法来设置一些web安全的细节
18 protected void configure(HttpSecurity http) throws Exception {
19 http
20 .authorizeRequests() //通过authorizeRequests()定义哪些URL需要被保护、哪些不需要被保护。
21 .antMatchers("/", "/home").permitAll() // /和/home不需要任何认证就可以访问。
22 .anyRequest().authenticated() //其他的路径都必须通过身份验证
23 .and()
24 .formLogin() //当需要用户登录时候
25 .loginPage("/login") //转到的登录页面
26 .permitAll()
27 .and()
28 .logout()
29 .permitAll();
30 }
31
32 @Autowired
33 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
34 auth
35 .inMemoryAuthentication() //在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为USER。
36 .withUser("user").password("password").roles("USER");
37 }
38
39}
40
4 启动类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 1package com.didispace;
2
3import org.springframework.boot.SpringApplication;
4import org.springframework.boot.autoconfigure.SpringBootApplication;
5
6@SpringBootApplication
7public class Application {
8
9 public static void main(String[] args) {
10
11 SpringApplication.run(Application.class, args);
12
13 }
14
15}
16
5 hello.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
4<head>
5 <title>Hello World!</title>
6</head>
7<body>
8<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
9<form th:action="@{/logout}" method="post">
10 <input type="submit" value="注销"/>
11</form>
12</body>
13</html>
14
6 index.html
1
2
3
4
5
6
7
8
9
10
11
12
13 1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
4<head>
5 <title>Spring Security入门</title>
6</head>
7<body>
8<h1>欢迎使用Spring Security!</h1>
9
10<p>点击 <a th:href="@{/hello}">这里</a> 打个招呼吧</p>
11</body>
12</html>
13
7 login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 1<!--
2Spring Security提供了一个过滤器来拦截请求并验证用户身份。
3如果用户身份认证失败,页面就重定向到/login?error,并且页面中会展现相应的错误信息。
4若用户想要注销登录,可以通过访问/login?logout请求,在完成注销之后,页面展现相应的成功消息。
5-->
6<!DOCTYPE html>
7<html xmlns="http://www.w3.org/1999/xhtml"
8 xmlns:th="http://www.thymeleaf.org"
9 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
10<head>
11 <title>Spring Security Example </title>
12</head>
13<body>
14<div th:if="${param.error}">
15 用户名或密码错
16</div>
17<div th:if="${param.logout}">
18 您已注销成功
19</div>
20<form th:action="@{/login}" method="post">
21 <div><label> 用户名 : <input type="text" name="username"/> </label></div>
22 <div><label> 密 码 : <input type="password" name="password"/> </label></div>
23 <div><input type="submit" value="登录"/></div>
24</form>
25</body>
26</html>
27
三 测试
1 启动应用程序
2 浏览器输入:http://localhost:8080/
3 点击页面中的“这里”链接,弹出下面页面
4 浏览器输入:http://localhost:8080/hello,弹出如下页面
5 输入一个错误的认证信息,然后点击登录,弹出如下页面
6 输入正确的认证信息,弹出如下页面
7 重开页面,浏览器输入http://localhost:8080/hello,弹出如下页面
8 点击注销,弹出页面如下