我们在编写Web应用时,经常需要对页面做一些安全控制,比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop、拦截器实现,也可以通过框架实现(如:Apache Shiro、Spring Security)。

本文将具体介绍在Spring Boot中如何使用Spring Security进行安全控制。

准备工作

首先,构建一个简单的Web工程,以用于后续添加安全控制,也可以用之前Chapter3-1-2做为基础工程。若对如何使用Spring Boot构建Web应用,可以先阅读《Spring Boot开发Web应用》一文。

Web层实现请求映射

@Controller
public class HelloController { @RequestMapping("/")
public String index() {
return "index";
} @RequestMapping("/hello")
public String hello() {
return "hello";
} }
  • /:映射到index.html
  • /hello:映射到hello.html

实现映射的页面

  • src/main/resources/templates/index.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入门</title>
</head>
<body>
<h1>欢迎使用Spring Security!</h1>
<p>点击 <a th:href="@{/hello}">这里</a> 打个招呼吧</p>
</body>
</html>
  • 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>

可以看到在index.html中提供到/hello的链接,显然在这里没有任何安全控制,所以点击链接后就可以直接跳转到hello.html页面。

整合Spring Security

在这一节,我们将对/hello页面进行权限控制,必须是授权用户才能访问。当没有权限的用户访问后,跳转到登录页面。

添加依赖

在pom.xml中添加如下配置,引入对Spring Security的依赖。

<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
...
</dependencies>

Spring Security配置

创建Spring Security的配置类WebSecurityConfig,具体如下:

@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");
} }
  • 通过@EnableWebSecurity注解开启Spring Security的功能
  • 继承WebSecurityConfigurerAdapter,并重写它的方法来设置一些web安全的细节
  • configure(HttpSecurity http)方法
    • 通过authorizeRequests()定义哪些URL需要被保护、哪些不需要被保护。例如以上代码指定了//home不需要任何认证就可以访问,其他的路径都必须通过身份验证。
    • 通过formLogin()定义当需要用户登录时候,转到的登录页面。
  • configureGlobal(AuthenticationManagerBuilder auth)方法,在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为USER。

新增登录请求与页面

在完成了Spring Security配置之后,我们还缺少登录的相关内容。

HelloController中新增/login请求映射至login.html

@Controller
public class HelloController { // 省略之前的内容... @RequestMapping("/login")
public String login() {
return "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}">
用户名或密码错
</div>
<div th:if="${param.logout}">
您已注销成功
</div>
<form th:action="@{/login}" method="post">
<div><label> 用户名 : <input type="text" name="username"/> </label></div>
<div><label> 密 码 : <input type="password" name="password"/> </label></div>
<div><input type="submit" value="登录"/></div>
</form>
</body>
</html>

可以看到,实现了一个简单的通过用户名和密码提交到/login的登录方式。

根据配置,Spring Security提供了一个过滤器来拦截请求并验证用户身份。如果用户身份认证失败,页面就重定向到/login?error,并且页面中会展现相应的错误信息。若用户想要注销登录,可以通过访问/login?logout请求,在完成注销之后,页面展现相应的成功消息。

到这里,我们启用应用,并访问http://localhost:8080/,可以正常访问。但是访问http://localhost:8080/hello的时候被重定向到了http://localhost:8080/login页面,因为没有登录,用户没有访问权限,通过输入用户名user和密码password进行登录后,跳转到了Hello World页面,再也通过访问http://localhost:8080/login?logout,就可以完成注销操作。

为了让整个过程更完成,我们可以修改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="注销"/>
</form>
</body>
</html>

本文通过一个最简单的示例完成了对Web应用的安全控制,Spring Security提供的功能还远不止于此,更多Spring Security的使用可参见Spring Security Reference

完整示例:Chapter4-3-1

Spring Boot中使用Spring Security进行安全控制的更多相关文章

  1. Spring Boot中使用 Spring Security 构建权限系统

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...

  2. 【swagger】1.swagger提供开发者文档--简单集成到spring boot中【spring mvc】【spring boot】

    swagger提供开发者文档 ======================================================== 作用:想使用swagger的同学,一定是想用它来做前后台 ...

  3. 在Spring Boot中使用Spring Security实现权限控制

    丢代码地址 https://gitee.com/a247292980/spring-security 再丢pom.xml <properties> <project.build.so ...

  4. Spring Boot中集成Spring Security 专题

    check to see if spring security is applied that the appropriate resources are permitted: @Configurat ...

  5. Spring Boot 中使用 Spring Security, OAuth2 跨域问题 (自己挖的坑)

    使用 Spring Boot 开发 API 使用 Spring Security + OAuth2 + JWT 鉴权,已经在 Controller 配置允许跨域: @RestController @C ...

  6. Spring Boot 中应用Spring data mongdb

    摘要 本文主要简单介绍下如何在Spring Boot 项目中使用Spring data mongdb.没有深入探究,仅供入门参考. 文末有代码链接 准备 安装mongodb 需要连接mongodb,所 ...

  7. spring boot中扩展spring mvc 源码分析

    首先,确认你是对spring boot的自动配置相关机制是有了解的,如果不了解请看我spring boot相关的源码分析. 通常的使用方法是继承自org.springframework.boot.au ...

  8. Spring Boot中使用Spring Security进行安全控制转载来自翟永超

    我们在编写Web应用时,经常需要对页面做一些安全控制,比如:对于没有访问权限的用户需要转到登录表单页面.要实现访问控制的方法多种多样,可以通过Aop.拦截器实现,也可以通过框架实现(比如:Apache ...

  9. spring-boot-starter-security Spring Boot中集成Spring Security

    spring security是springboot支持的权限控制系统. security.basic.authorize-mode 要使用权限控制模式. security.basic.enabled ...

随机推荐

  1. 条形码生成库 BarcodeLib

    官方介绍 在ASP.NET,Windows,Reporting Service,Crystal Reports 和 RDLC Reports应用程序中轻松生成条形码 生成准确的条形码图像,并可以保存为 ...

  2. Django之ORM对数据库操作

    基本操作 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): ...

  3. zepto中$.proxy()的到底有多强大?

    好吧,其实是标题党了,哈哈,只是想总结一下工作中遇到$.proxy()的用法而已. 一.语法: $.proxy()有两种使用语法 1)$.proxy(fn,context),fn是一个函数,conte ...

  4. [HNOI2014]江南乐 博弈论

    题面 题面 题解 首先我们知道一个关于除法的重要性质:对于一个固定的\(i\),表达式\(\frac{i}{m}\)的取值只有根号个. 因此我们考虑如何优化SG函数的求解. 观察到在取值相同的同一段中 ...

  5. 【BZOJ2138】stone(线段树,Hall定理)

    [BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...

  6. 【BZOJ4300】绝世好题(动态规划)

    [BZOJ4300]绝世好题(动态规划) 题面 BZOJ Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=l ...

  7. NOIP2017 考前汇总

    时隔一年,相比去年一无所知的自己,学到了不少东西,虽然还是很弱,但也颇有收获[学会了打板QAQ] 现在是2017.11.9   21:10,NOIP2017的前两天晚上,明天就要出发,做最后的总结 N ...

  8. 洛谷 P1501 [国家集训队]Tree II 解题报告

    P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...

  9. Caffe框架详细梳理

    protobuf是google公司开发的,并在Google内部久经考验的一个东西,在08年google把它贡献给了开源社区,随后便有越来越多的人使用它.protobuf是一个结构化信息传递的工具,主要 ...

  10. 【分块,莫队】【P4396】【AHOI2013】作业

    传送门 Description 此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可以做完的数学作业,接下来是分别都是一个小时 ...