简介

作为 Spring 全家桶组件之一,Spring Security 是一个提供安全机制的组件,它主要解决两个问题:

  • 认证:验证用户名和密码;
  • 授权:对于不同的 URL 权限不一样,只有当认证的用户拥有某个 URL 的需要的权限时才能访问。

Spring Security 底层使用的是过滤器,针对 URL 进行的拦截,对应到 Java 中也就是类; 因此被称为粗粒度授权验证,就是验证 URL ,当前用户是否有这个 URL 的权限。

入门

创建项目

使用 Idea 创建 Spring Boot 项目,勾选需要的组件:

  • Spring Web
  • Spring Security

或者创建项目后添加依赖:

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

这里使用的是 JSP 作为模板,有关如何在 Spring Boot 中使用 JSP 作为模板请访问:https://www.cnblogs.com/cloudfloating/p/11787222.html

WebSecurityConfig

package top.cloudli.demo.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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; @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = new BCryptPasswordEncoder(); auth.inMemoryAuthentication()
.passwordEncoder(encoder)
.withUser("root")
.password(encoder.encode("root@123456"))
.roles("ROOT", "USER")
.and()
.withUser("user")
.password(encoder.encode("user@123456"))
.roles("USER");
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**")
.permitAll() // css 不用验证
.anyRequest()
.authenticated() // 其它页面全部需要验证
.and()
.formLogin() // 使用默认登录页面
.and()
.exceptionHandling()
.accessDeniedPage("/401") // 无权限时跳转的页面
.and()
.logout();
}
}
  • @EnableWebSecurity 注解启用验证;
  • @EnableGlobalMethodSecurity(prePostEnabled=true) 注解允许我们在控制器的方法中使用 @PreAuthorize 实现权限分割。

此处创建了两个用户并保存在内存中,分别是拥有 ROOT 和 USER 权限的 root 用户和仅拥有 USER 权限的 user 用户。

fromLogin() 方法可以接着调用 loginPage() 指定一个自定义登录页面,这里使用的是默认登录页面。

编写页面

1.index.jsp,所有通过验证的用户都可以访问:

<%--
任何通过验证的用户都能访问的页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Spring Security Demo Application</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="content">
<h1>Spring Security In Memory Authentication</h1>
<h2>这是被保护的页面(ROLE_USER)。</h2>
</div>
</body>
</html>

2.root.jsp,只有拥有 ROOT 权限的用户能访问:

<%--
需要 ROLE_ROOT 才能访问的页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Root Page</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="content">
<h1>Root Page</h1>
<h2>你正在访问受保护的页面(ROLE_ROOT)。</h2>
</div>
</body>
</html>

3.401.jsp,没有权限时跳转的页面:

<%--
权限不够时跳转的页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>401 Unauthorized</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body class="error">
<div class="content">
<h1>401 Unauthorized!</h1>
<h2>你没有权限访问此页面。</h2>
</div>
</body>
</html>

控制器

package top.cloudli.demo.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; @Controller
public class DemoController { @PreAuthorize("hasAnyAuthority('ROLE_USER')")
@GetMapping("/")
public String index() {
return "index";
} @PreAuthorize("hasAnyAuthority('ROLE_ROOT')")
@GetMapping("/root")
public String root() {
return "root";
} @GetMapping("/401")
public String accessDenied() {
return "401";
}
}

@PreAuthorize 注解指定了访问页面所需要的权限,这里的权限要加上 ROLE_ 前缀。

Run

访问 http://localhost:8080/ 将进入登录页面(这里使用的是 Spring Security 的默认登录页面):

使用刚才创建的内存用户 user 登录后将返回 index 页面:

访问 http://localhost:8080/root,由于 user 用户没有 ROLE_ROOT 权限,跳转到 401 页面:

访问 http://localhost:8080/logout 将进入默认登出页面:

这里的登录和登出页面均可以使用自定义页面,只需要在自定义的页面中把数据通过 PSOT 请求提交到 /login/logout 即可完成登录和登出。

Spring Security 入门—内存用户验证的更多相关文章

  1. Spring security 浅谈用户验证机制

    step1:首先ApplicationUserDetailsService需要实现UserDetailsService接口(在 org.springframework.security.core.us ...

  2. 030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门

    1.权限操作涉及的三张表 (1)用户表信息描述users sql语句: CREATE TABLE users ( id ) DEFAULT SYS_GUID () PRIMARY KEY, email ...

  3. SpringBoot集成Spring Security入门体验

    一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...

  4. Spring Security 入门(基本使用)

    Spring Security 入门(基本使用) 这几天看了下b站关于 spring security 的学习视频,不得不说 spring security 有点复杂,脑袋有点懵懵的,在此整理下学习内 ...

  5. Spring security 获取当前用户

    spring security中当前用户信息 1:如果在jsp页面中获取可以使用spring security的标签库 在页面中引入标签   1 <%@ taglib prefix=" ...

  6. Spring Security 入门(1-7)Spring Security - Session管理

    参考链接:https://xueliang.org/article/detail/20170302232815082 session 管理 Spring Security 通过 http 元素下的子元 ...

  7. Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制

    登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...

  8. Spring Security入门(2-3)Spring Security 的运行原理 4 - 自定义登录方法和页面

    参考链接,多谢作者: http://blog.csdn.net/lee353086/article/details/52586916 http元素下的form-login元素是用来定义表单登录信息的. ...

  9. Spring Security默认的用户登录表单 页面源代码

    Spring Security默认的用户登录表单 页面源代码 <html><head><title>Login Page</title></hea ...

随机推荐

  1. weblogic删除域

    彻底删除weblogic域的方法: 例如:删除域名为:fm_ump的域 第一步,删除域注册记录: [bofm@UAT02-BIZ-ZJCG-AP-008 Middleware]$ cd /home/s ...

  2. 【PHP】关于系统性能追踪工具molten

    一.简介 关于molten的介绍网上有很多,是一个全链路追踪的工具,Molten可以看做是phptrace的的升级版(流行的php问题定位工具譬如phptrace,xhprof,这些工具可以自行Goo ...

  3. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

  4. 第 33课 C++中的字符串(下)

    字符串与数字转换-标准库中提供了相关的类对字符串和数字进行转换-字符串流类(sstream)用于string的转换.<sstream>-相关头文件.istringstream-字符串输入流 ...

  5. 201871010105-曹玉中《面向对象程序设计(java)》第十周学习总结

    201871010105-曹玉中<面向对象程序设计(java)>第十周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...

  6. springboot+springcloud微服务项目全套资料(笔记+源码+代码)

    最近好几天没有写博客了,由于时间的太忙了,项目要做.各种资格证要考试,实在没有时间写了,今天正好赶上有闲暇的一刻,应许多的爱好者的要求发一份微服务项目的资料,此资料十分完整,且是最新的.希望各位读者能 ...

  7. JAVA HashMap与ConcurrentHashMap

    HashMap Fast-Fail(遍历时写入操作异常) 在使用迭代器的过程中如果HashMap被修改,那么ConcurrentModificationException将被抛出,也即Fast-fai ...

  8. .net使用IIdentity和IPrincipal实现自定义身份及权限认证【转】

    1,通过继承BasePage页实现角色权限控制 context.User中保存的信息就是相关的角色与权限信息.Context.User类型为System.Security.Principal.IPri ...

  9. map、set 使用方法 | 1022 图书馆信息查询

    看了答案才知道了这题的各种骚操作,然后敲了一顿骚键盘,然后wa.调了很久,才发现要规格化打印……mdzz…… 注:加粗代码为傻逼规格化打印代码: #include <stdio.h> #i ...

  10. Linux性能优化实战学习笔记:第五十五讲

    一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...