首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用SpringSecurity

使用SpringSecurity

作者头像
dalaoyang
发布于 2018-06-11 06:41:55
发布于 2018-06-11 06:41:55
78700
举报
文章被收录于专栏:dalaoyangdalaoyang
运行总次数:0

前几天写了一个SpringBoot对拦截器的使用,在实际项目中,对一些情况需要做一些安全验证,比如在没有登录的情况下访问特定的页面应该解释的拦截处理。这一篇介绍使用SpringSecurity来做简单的安全控制,由于SpringSecurity比较复杂,如果有不对的地方可以大家一起学习。

新建项目,前端页面使用thymeleaf,加入security依赖,pom文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dalaoyang</groupId>
    <artifactId>springboot_security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot_security</name>
    <description>springboot_security</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

配置文件本文就是将之前整合thymeleaf的配置拿了过来,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##端口号
server.port=8888


##去除thymeleaf的html严格校验
spring.thymeleaf.mode=LEGACYHTML5

#设定thymeleaf文件路径 默认为src/main/resources/templates
spring.freemarker.template-loader-path=classpath:/templates
#设定静态文件路径,js,css等
spring.mvc.static-path-pattern=/static/**
# 是否开启模板缓存,默认true
# 建议在开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
# 模板编码
spring.freemarker.charset=UTF-8

接下来是这篇文章重要的地方,新建一个SecurityConfig类,继承WebSecurityConfigurerAdapter类,重写configure(HttpSecurity httpSecurity)方法,其中/css/**和/index的资源不需要验证,直接可以请求,/user/**的资源需要验证,权限是USER,/admin/**的资源需要验证,权限是ADMIN,登录地址是/login,登录失败地址是/login_error,异常重定向到 /401,注销跳转到/logout。 注入AuthenticationManagerBuilder,在内存中创建一个用户dalaoyang,密码123的用户,权限是USER,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.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.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;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.config
 * @email yangyang@dalaoyang.cn
 * @date 2018/4/28
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // /css/**和/index的资源不需要验证,直接可以请求
    // /user/**的资源需要验证,权限是USER /admin/**的资源需要验证,权限是ADMIN
    // 登录地址是/login 登录失败地址是 /login_error
    // 异常重定向到 /401
    // 注销跳转到 /logout
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception{
        httpSecurity
                .authorizeRequests()
                .antMatchers("/css/**","/index").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasRole("ADMIN")
                .and()
                .formLogin().loginPage("/login").failureUrl("/login_error")
                .and()
                .exceptionHandling().accessDeniedPage("/401");

        httpSecurity.logout().logoutSuccessUrl("/logout");
    }


    //内存中创建用户,用户名为dalaoyang,密码123,权限是USER
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("dalaoyang").password("123").roles("USER");
    }
}

创建一个TestController负责跳转,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.controller
 * @email yangyang@dalaoyang.cn
 * @date 2018/4/28
 */
@Controller
public class TestController {

    @RequestMapping("/")
    public String index(){
        return "index";
    }

    @RequestMapping("/index")
    public String index2(){
        return "index";
    }

    @RequestMapping("/user")
    public String user(){
        return "user/index";
    }

    @RequestMapping("/admin")
    public String admin(){
        return "admin/index";
    }

    @RequestMapping("/login")
    public String login(){
        return "login";
    }

    @RequestMapping("/login_error")
    public String login_error(Model model){
        model.addAttribute("login_error", "用户名或密码错误");
        return "login";
    }

    @RequestMapping("/logout")
    public String logout(Model model){
        model.addAttribute("login_error", "注销成功");
        return "login";
    }

    @RequestMapping("/401")
    public String error(){
        return "401";
    }
}

创建一个user/index.html,用于校验USER权限,没有登录的话不能直接访问,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>user/index</title>
</head>
<body>
user/index

<form th:action="@{/logout}" method="post">
    <input type="submit" value="注销"/>
</form>
</body>
</html>

创建一个admin/index.html,只允许ADMIN权限访问,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>admin</title>
</head>
<body>
admin/index
</body>
</html>

401页面,用于没有权限跳转:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>401</title>
</head>
<body>
401
</body>
</html>

index页面,任何权限都能访问

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
index
</body>
</html>

login页面,用于登录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
<h1>login</h1>
<form th:action="@{/login}" method="post">
    <span th:text="${login_error}"></span>
<br/>
    <input type="text" name="username">用户名<br/>
<input type="password" name="password">密码<br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

到这里就全部创建完成了,启动项目,访问http://localhost:8888/,如图,可以直接访问。

访问http://localhost:8888/user被拦截到http://localhost:8888/login,如图

先输入错误的密码,如图

然后输入用户名dalaoyang密码123,点击登录结果如图

访问http://localhost:8888/admin,如图,没有权限

我们在回到http://localhost:8888/user点击注销,如图

源码下载 :大老杨码云

个人网站:https://dalaoyang.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
吃透二分查找—— LeetCode 第 33、34、35 题记
昨天没能完成 34,今天来补上。恰好第 35 题也是二分查找算法的应用,放到一起来记录。
TTTEED
2020/07/09
2K0
二分查找团灭力扣旋转排序数组系列
Leetcode 中有一系列旋转排序数组相关的问题,例如33. 搜索旋转排序数组、81. 搜索旋转排序数组 II、153. 寻找旋转排序数组中的最小值、154. 寻找旋转排序数组中的最小值 II 和面试题10.03 搜索旋转数组等,本文介绍通过二分查找团灭这一系列问题,供大家参考,希望能对大家有所帮助。
程序员小熊
2021/05/28
6620
二分查找团灭力扣旋转排序数组系列
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
Michael阿明
2020/07/13
2.2K0
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
LeetCode 33. 搜索旋转排序数组(二分查找)
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
Michael阿明
2020/07/13
3420
LeetCode 33. 搜索旋转排序数组(二分查找)
深度解析算法之二分查找(2)
题目链接 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
Undoom
2025/04/20
2100
深度解析算法之二分查找(2)
Leetcode | 第4节:二分查找,归并排序
上一节我们说完了链表的一些高频题。那么这一节,我们会介绍一些二分查找和排序相关的题目。二分和排序本身不是很困难,但是还是有一些难题需要一些技巧才能解决(倒也不是完全毫无头绪的那种),所以这一篇文章,我们除了基本内容外,也会花一些时间介绍一下技巧性的内容。
学弱猹
2021/08/10
5980
Leetcode | 第4节:二分查找,归并排序
面试前必知必会二分查找及其变种
今天给大家带来的是二分查找及其变种的总结,大家一定要看到最后呀,用心满满,废话不多说,让导演帮我们把镜头切到袁记菜馆吧!
公众号袁厨的算法小屋
2020/12/19
1.4K0
LeetCode-算法-二分查找-第15天
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。
布衣者
2021/09/07
3040
【算法专题】二分查找
题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 - 1。
YoungMLet
2024/03/01
2270
【算法专题】二分查找
【优选算法篇】寻找隐藏的宝藏:用二分查找打开算法世界的大门(上篇)
二分查找(Binary Search)是一种经典的算法,广泛应用于计算机科学中,尤其在处理有序数据时。其重要性体现在以下几个方面:
熬夜学编程的小王
2024/12/24
3260
【优选算法篇】寻找隐藏的宝藏:用二分查找打开算法世界的大门(上篇)
穿了好几个马甲,差点没认出来是二分查找
今天给大家带来的是二分查找及其变种的总结,大家一定要看到最后呀,非常非常用心的一篇文章,废话不多说,让导演帮我们把镜头切到袁记菜馆吧!
公众号袁厨的算法小屋
2020/12/22
6650
穿了好几个马甲,差点没认出来是二分查找
二分查找总结
二分查找是在每次匹配后,将查找的空间一分为二的算法,二分查找应该是有序的数组进行查找.
Tim在路上
2020/08/04
5370
【优选算法篇】在分割中追寻秩序:二分查找的智慧轨迹
给定一个升序排列的整数数组 nums,和一个目标值 target。如果 target 在数组中存在,返回其下标;否则,返回 -1。
半截诗
2024/10/22
3910
【刷题】 二分查找入门
总有一天,你会站在最亮的地方,活成自己曾经渴望的模样—— 苑子文 & 苑子豪《我们都一样 年轻又彷徨》
叫我龙翔
2024/04/02
1840
【刷题】 二分查找入门
【二分算法】——8个题目让你找到二分算法的感觉势如破竹
https://leetcode.cn/problems/binary-search/
用户11286421
2024/10/12
6350
【二分算法】——8个题目让你找到二分算法的感觉势如破竹
【oj刷题】二分查找篇:二分查找算法的原理和应用场景
二分查找一般是基于有序数组的,通过比较目标值与中间元素的大小关系,来决定是在数组的左侧还是右侧继续搜索。
GG Bond1
2024/09/21
6860
【oj刷题】二分查找篇:二分查找算法的原理和应用场景
LeetCode题目33:搜索旋转排序数组
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
二环宇少
2020/08/13
5630
LeetCode题目33:搜索旋转排序数组
[算法总结] 二分查找
二分查找法作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围,大大缩短了搜索时间,但它有一个前提,就是必须在有序数据中进行查找。
尾尾部落
2018/09/04
8470
【每日一题】33. Search in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
公众号-不为谁写的歌
2020/08/11
4010
【每日一题】33. Search in Rotated Sorted Array
二分查找的通用模板
二分查找适用于对于有序数组的精确查找,例如从一个有序数组中找到指定元素的索引,可将时间复杂度从普通枚举的 O(n) 降至 O(log n) ,前提是数组必须是有序的,否则是没有办法使用二分查找的。二分查找的思想虽然简单,不过在实现过程中会有很多细节问题需要注意,例如判断循环是用left < right还是用left <= right,right是取最右的元素还是取数组的边界。本文想通过七个例题,约定一种规则或是模板,从此让写二分查找不再出现模棱两可的局面。
兜兜转转
2023/03/08
1.1K0
推荐阅读
相关推荐
吃透二分查找—— LeetCode 第 33、34、35 题记
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档