spring boot学习第十三篇:使用spring security控制权限

该文章同时也讲到了如何使用swagger。

1、pom.xml文件内容如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.hmblogs</groupId>
	<artifactId>springboot-security-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-security-demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!--devtools热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>
	
		<!--  springboor-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
       </dependency>
	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

		<!-- swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
	</dependencies>

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

</project>

2、application.yml文件内容如下:

server:
  port: 8088
  servlet:
    context-path: /springboot-security-demo
    
spring:
  security:
    user:
      name: user
      password: 123456

3、SpringbootSecurityDemoApplication文件内容如下:

package com.hmblogs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootSecurityDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootSecurityDemoApplication.class, args);
	}

}

4、UserDetailsServiceImpl代码如下:

package com.hmblogs.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.hmblogs.pojo.Admin;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

	@Override
	public UserDetails loadUserByUsername(String username) {
		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
		Admin admin = new Admin();
		
		if (username.equals("employee")) {
			admin.setUsername("employee");
			admin.setPassword("123456");
			GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_EMPLOYEE");
			grantedAuthorities.add(grantedAuthority);
			// 创建用户,用户判断权限
			return new User(
					admin.getUsername(), 
					new BCryptPasswordEncoder().encode(admin.getPassword()), 
					grantedAuthorities);
		} 
		
		if (username.equals("admin")) {
			admin.setUsername("admin");
			admin.setPassword("123456");
			GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
			grantedAuthorities.add(grantedAuthority);
			// 创建用户,用户判断权限
			return new User(
					admin.getUsername(), 
					new BCryptPasswordEncoder().encode(admin.getPassword()), 
					grantedAuthorities);
		}
		
		return null;
	}

}

5、Admin这一个对象类代码如下:

package com.hmblogs.pojo;


public class Admin {

	private String username;
	
	private String password;

	public Admin() {
		super();
	}

	public Admin(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "Admin [username=" + username + ", password=" + password + "]";
	}
	
}

6、TestController测试接口类代码如下所示:

package com.hmblogs.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test/")
public class TestController {

	@RequestMapping(value = "get", method = RequestMethod.GET)
	public String get() {
		return "success";
	}
	
}

7、EmployeeController员工权限的员工接口类代码如下所示:

package com.hmblogs.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/employee/")
public class EmployeeController {

	@RequestMapping(value = "greeting", method = RequestMethod.GET)
	public String greeting() {
		return "hello world";
	}
	
	@RequestMapping(value = "login", method = RequestMethod.GET)
	public String login() {
		return "login success";
	}
	
}

8、AdminController管理员接口类的代码如下所示:

package com.hmblogs.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/admin/")
public class AdminController {

	@RequestMapping(value = "greeting", method = RequestMethod.GET)
	public String greeting() {
		return "hello world";
	}
	
	@RequestMapping(value = "login", method = RequestMethod.GET)
	public String login() {
		return "login success";
	}
	
}

9、SwaggerConfig代码如下:配置swagger

package com.hmblogs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

	@Bean
    public Docket createRestApi(){
        // 添加请求参数,我们这里把token作为请求头部参数传入后端
		return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .select().apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("SpringBoot API Doc")
                .description("This is a restful api document of Spring Boot.")
                .version("1.0")
                .build();
    }
	
}

10、SecurityConfig代码如下:

package com.hmblogs.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private UserDetailsService userDetailsService;
	
	@Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
	
	@Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
    	auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());//passwoldEncoder是对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()//禁用了 csrf 功能
                .authorizeRequests()//限定签名成功的请求
                .antMatchers("/decision/**","/govern/**","/employee/*").hasAnyRole("EMPLOYEE","ADMIN")//对decision和govern 下的接口 需要 EMPLOYEE 或者 ADMIN 权限
                .antMatchers("/employee/login").permitAll()///employee/login 不限定
                .antMatchers("/admin/**").hasRole("ADMIN")//对admin下的接口 需要ADMIN权限
                .antMatchers("/oauth/**").permitAll()//不拦截 oauth 开放的资源
                .anyRequest().permitAll()//其他没有限定的请求,允许访问
                .and().anonymous()//对于没有配置权限的其他请求允许匿名访问
                .and().formLogin()//使用 spring security 默认登录页面
                .and().httpBasic();//启用http 基础验证

    }
	
}

11.CorsConfig文件代码如下:

package com.hmblogs.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer{

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")    // 允许跨域访问的路径
        .allowedOrigins("*")    // 允许跨域访问的源
        .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")    // 允许请求方法
        .maxAge(168000)    // 预检间隔时间
        .allowedHeaders("*")  // 允许头部设置
        .allowCredentials(true);    // 是否发送cookie
	}
	
}

12、启动该微服务,验证。

12.1访问http://localhost:8088/springboot-security-demo/swagger-ui.html

这里我如果用户名输入admin,密码输入123456,点击登录

清除浏览器缓存后,再使用employee和123456登录,则会报401

admin账号能使用admin接口,但是employee账号不能使用admin接口。

 12.2使用admin账号密码和empoyee账号密码尝试employee接口,

先试用admin账号密码登录

清除浏览器缓存,再使用employee账号密码登录

点击登录后,查看响应,如下:

admin和employee账号都能正常访问employee接口

达到了预期目的。 

代码参考:https://github.com/veminhe/spring-security-demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/417943.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为配置WLAN高密业务示例

配置WLAN高密业务示例 组网图形 图1 配置高密WLAN环境网络部署组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 体育场由于需要接入用户数量很大&#xff0c;AP间部署距离较小&#xff0c;因此AP间的干扰较大&#xff0c;可能导致用户上网网…

PostgreSQL从入门到精通教程 - 第45讲:poc-tpcc测试

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第45讲&#…

【知识整理】Git 使用实践问题整理

问题1、fatal: refusing to merge unrelated histories 一、Git 的报错 fatal: refusing to merge unrelated histories 新建了一个仓库之后&#xff0c;把本地仓库进行关联提交、拉取的时候&#xff0c;出现了如下错误&#xff1a; fatal: master does not appear to be a g…

状态码转文字!!!(表格数字转文字)

1、应用场景&#xff1a;在我们的数据库表中经常会有status这个字段&#xff0c;这个字段经常表示此类商品的状态&#xff0c;例如&#xff1a;0->删除&#xff0c;1->上架&#xff0c;0->下架&#xff0c;等等。 2、我们返回给前端数据时&#xff0c;如果在页面显示0…

C语言实现21点游戏【单人模式,双人模式,单-多电脑模式】,21点又名黑杰克(英文:Blackjack)

项目背景&#xff1a; 21点又名黑杰克&#xff08;英文&#xff1a;Blackjack&#xff09; &#xff0c;起源于法国&#xff0c;已流传到世界各地。21点&#xff0c;是一种使用扑克牌玩的赌博游戏。亦是唯一一种在赌场中可以在概率中战胜庄家的一种赌博游戏。 现在在世界各地…

计算机网络原理--传输层

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 TCP/IP五层&#xff08;或四层&#xff09;模型 传输层 TCP和UDP的区别 UDP协议 校验和 如何…

【Unity】如何设置Unity脚本的执行顺序?

在 Unity 编辑器中设置脚本执行顺序 在 Unity 中&#xff0c;如果有多个脚本&#xff0c;并且它们之间的执行顺序很重要&#xff0c;可以通过编辑器设置来确保它们按照自己期望的顺序执行。这对于确保某些脚本在其他脚本之前执行非常有用。在这篇文章中&#xff0c;将向会展示如…

Kubernetes IoTDB系列 | IoTDB数据库同步|IoTDB数据库高可用 | v1.3.0

目录 一、介绍二、应用场景三、IoTDB 数据库搭建四、数据同步一、介绍 IoTDB 数据同步功能可以将 IoTDB 的数据传输到另一个数据平台,我们将一个数据同步任务称为 Pipe。 一个 Pipe 包含三个子任务(插件): 抽取(Extract)处理(Process)发送(Connect)Pipe 允许用户自…

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…

强化学习Agent系列(二)——PyGame虚拟环境创建与Python 贪吃蛇Agent制作实战教学

文章目录 一、前言二、gymnasium 简单虚拟环境创建1、gymnasium介绍2、gymnasium 贪吃蛇简单示例 三、基于gymnasium创建的虚拟环境训练贪吃蛇Agent1、虚拟环境2、虚拟环境注册3、训练程序4、模型测试 三、卷积虚拟环境1、卷积神经网络虚拟环境2、训练代码 一、前言 大家好&am…

300分钟吃透分布式缓存(拉钩教育总结)

开篇寄语 开篇寄语&#xff1a;缓存&#xff0c;你真的用对了吗&#xff1f; 你好&#xff0c;我是你的缓存老师陈波&#xff0c;可能大家对我的网名 fishermen 会更熟悉。 我是资深老码农一枚&#xff0c;经历了新浪微博从起步到当前月活数亿用户的大型互联网系统的技术演进…

NebulaGraph入门

感谢阅读 官方文档链接NebulaGraph简介nGQLnGQL简介占位标识符和占位符值注释实列大小写区分关键字 基本概念以及相关代码实现补充说明图空间语法以及列子创建克隆官方示例代码(创建并克隆)USE语句指定图空间时查看所有SPACESPACE详情CLEAR SPACE删库跑路&#xff08;看玩笑的说…

C语言:字符函数 字符串函数 内存函数

C语言&#xff1a;字符函数 & 字符串函数 & 内存函数 字符函数字符分类函数字符转换函数tolowertoupper 字符串函数strlenstrcpystrcatstrcmpstrstrstrtok 内存函数memcpymemmovememsetmemcmp 字符函数 顾名思义&#xff0c;字符函数就是作用于字符的函数&#xff0c;…

3dgs学习(二)—— 3d高斯与协方差矩阵及其几何意义

协方差矩阵与3d高斯 3d高斯与椭球与协方差矩阵 3d高斯&#xff0c;及3维空间内的正态分布。 通过一元正态分布的坐标系图像不难想象&#xff0c;3维空间中的正态分布点集中在一片椭球空间中&#xff0c;各方向长轴取决于各方向正态分布的方差。 而协方差矩阵通过计算多元之…

好物周刊#42:国产项目管理软件

https://github.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. 菠萝博客 基于 Java 的菠萝博客系统&#xff0c;简单易部署&#xff0c;精致主题&#xff0c;贴心服务&#xf…

本届挑战赛亚军方案:面向微服务架构系统中无标注、多模态运维数据的异常检测、根因定位与可解释性分析

CheerX团队来自于南瑞研究院系统平台研发中心&#xff0c;中心主要从事NUSP电力自动化通用软件平台的关键技术研究与软件研发。 选题分析 图1 研究现状 本次CheerX团队的选题紧密贴合了目前的运维现状。实际运维中存在多种问题导致运维系统的不可用。比如故障发生时&#xff…

【常用】【测速】ptflops库---速度FPS、参数Params、计算复杂度Flops

一、常用名字 中文名字 英文名字 简称 单位 模型参数量 number of parameters. param. (单位B M) 计算复杂度 computational…

【Spring Cloud 进阶】OpenFeign 底层原理解析

参考文章 万字33张图探秘OpenFeign核心架构原理 | 三友SpringCloud OpenFeign源码详细解析Java 代理机制 OpenFeign 是一个精彩的使用动态代理技术的典型案例&#xff0c;通过分析其底层实现原理&#xff0c;我们可以对动态代理技术有进一步的理解。 目录 1. Feign 与 OpenFeig…

VUE3:统计分析页面布局+自适应页面参考

一、布局 <template><div class"container1"><div class"form white"><el-form :inline"true" :rules"rules" :model"queryParams" label-width"80px" ref"querParmRef"><e…

力扣递归:路径总和

思路&#xff1a;此题思路为递归实现&#xff0c;递归思路为&#xff1a;在每层递归的过程中将各个节点的数据记录下来&#xff0c;不断将减少目标数据的值准备进行判断&#xff0c;当进行到叶子节点时要进行判断 /*** Definition for a binary tree node.* struct TreeNode {…