Springboot利用Security做OAuth2授权验证

news2024/12/26 0:10:37

OAuth2获取授权令牌(token)通常有四种方式:授权码模式,简化模式,客户端模式,和密码模式。针对自己系统内用户的登录,通常使用密码模式进行授权。

我们利用Spring Security OAuth2来制作一个授权服务器。

第一步 添加依赖

pom文件中添加如下依赖,引入oauth2相关框架

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

我还是用到了数据库进行存储,我用的jpa连接数据库,使用其他持久层框架(MyBatis)也可以。

引入数据库依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--数据库链接驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

第二步 添加代码

1 实现UserDetailsService,获取用户

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名获取用户,并验证用户是否有效及权限
        //从数据库中获取用户
        TUser user = userService.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        boolean enabled = user.getStatus() == 1; // 可用性 :true:可用 false:不可用
        boolean accountNonExpired = true; // 过期性 :true:没过期 false:过期
        boolean credentialsNonExpired = true; // 有效性 :true:凭证有效 false:凭证无效
        boolean accountNonLocked = true; // 锁定性 :true:未锁定 false:已锁定
        //配置权限
        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ADMIN");
        grantedAuthorities.add(grantedAuthority);

        //将用户名和密码及其他配置返还个spring security 进行验证
        return new User(username, user.getPassword(),
                enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities);
    }

}

2 添加WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


}

3 添加AuthorizationServerConfigurerAdapter

@Configuration
@EnableAuthorizationServer
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {

    //验证管理器
    @Resource
    private AuthenticationManager authenticationManager;

    //获取用户,自己实现获取用户的相关功能
    @Resource
    private MyUserDetailsService userService;

    //数据库配置
    @Resource
    private DataSource dataSource;

    /**
     * 自定义授权服务配置
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService)
                .tokenStore(new JdbcTokenStore(dataSource));

        // 配置TokenServices参数
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(endpoints.getTokenStore());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
        tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
        tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(12)); // 12小时
        tokenServices.setRefreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30));// 30天
        endpoints.tokenServices(tokenServices);
    }

    /**
     * 配置认证客户端
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //自定义客户端配置
        clients.withClientDetails(clientDetails());
    }

    //从数据库中获取客户端的配置
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }

    /**
     * 自定义授权令牌端点的安全约束
     * @param security
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        //自定义安全约束
        security.allowFormAuthenticationForClients();
    }

}

第三步 初始化数据库

在数据库中创建三个表 oauth_access_token (存储token),oauth_client_details(允许请求授权的客户端),oauth_refresh_token(存储refreshToken)

为了测试,我还建了一个t_user的用户表,这个表可以不导入

CREATE TABLE `oauth_access_token`  (
  `token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `token` blob NULL,
  `authentication_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authentication` blob NULL,
  `refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;


CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `access_token_validity` int(11) NULL DEFAULT NULL,
  `refresh_token_validity` int(11) NULL DEFAULT NULL,
  `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- 初始化了一个客户端的数据
INSERT INTO `oauth_client_details` VALUES ('client', '', '$2a$10$My8G.sWJs/WQN8hdYS862.BsUuoL4p51xyfTIJu2NMMrIQ/JXRc2a', 'web', 'authorization_code,password,refresh_token,client_credentials', NULL, NULL, NULL, NULL, '{\"code\":\"test\"}', NULL);

DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token`  (
  `token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `token` blob NULL,
  `authentication` blob NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;


-- 我自己测试用的用户表,这个可以不导入,使用自己系统的用户表
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '昵称',
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
  `status` int(11) NULL DEFAULT NULL COMMENT '状态 1正常 2停用',
  `e_mail` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电子邮箱',
  `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `t_user` VALUES (1, 'admin', '管理员', '$2a$10$gD1u5uXEmCFmlvg.hgN7P.zv.sbCOEmX1sFNRHEBRIx6Ad.qydceu', 1, 'admin@admin.com', '15812345678');

在application中配置数据库信息

spring:
  application:
    name: HelloSecurity
  #数据库配置连接
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/hello_security?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: "123456"
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    show-sql: true

server:
  port: 8080

完成以上步骤后,一个简单的OAuth2授权验证服务器就搭建完成了,我们启动项目,进行测试。

获取token的接口是 http://127.0.0.1:8080/oauth/token

 源码地址:https://gitee.com/xiaobailovejiajia/hello-security

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django健身生活系统论文

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Java】从源码分析fail-fast和fail-safe是如何产生的

文章目录fail-fastfail-safe这个问题出现在使用Iterator迭代器的时候。如果某一个集合在使用的时候&#xff0c;另一个线程修改了这个集合&#xff0c;会出现什么情况呢&#xff1f;因此就出现了两种解决策略fail-fast 一旦发现遍历的同时其它人来修改&#xff0c;则立刻抛异常…

【微信小程序】页面跳转、组件自定义、获取页面参数值

&#x1f3c6;今日学习目标&#xff1a;第十七期——页面跳转、组件自定义、获取页面参数值 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰预计时间&#xff1a;25分钟 &#x1f389;专栏系列&#xff1a;我的第一个微信小程序 文章目…

推荐系统相关论文阅读整理

文章题目 基于协同过滤的微信点餐推荐系统的设计与实现 作者 张彭飞 吉林大学 期刊论文在线阅读—中国知网 (cnki.net)摘要关键词协同过滤;推荐系统;Docker;PXC;RedisCluster;名词解释文献研究目的推荐系统应用现状 在1990 年代&#xff0c;为了解决邮件过载问题&#xff0c…

如此简单的k8s,快速玩转ingress

如此简单的k8s&#xff0c;快速玩转ingress NodePort 可以实现的功能和缺陷&#xff1a; 功能、在每一个节点上面都会启动一个端口&#xff0c;在访问的时候通过任何的节点&#xff0c;通过节点加ip的形式实现访问 缺点、也就是说每个端口只能使用一次&#xff0c;一个端口对应…

传输层协议 —— TCP(图解1)

目录 一、TCP的基本认识 1. TCP头部格式 2. TCP协议的特点 3. 什么是TCP连接 4. TCP如何封装与分用 二、通过序列号和确认应答号提高可靠性 1. 32位序列号 2. 32位确认应答号 3. 保证可靠性 4. 为什么序列号和确认应答号是单独的字段 三、窗口大小 1. TCP的发送和…

[附源码]JAVA毕业设计敬老院管理系统(系统+LW)

[附源码]JAVA毕业设计敬老院管理系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&a…

ubuntu 实现远程开关机

1. 需求 家里厅里有三台linux主机在跑虚拟机, 一台windows主机在跑wsl2 - ubuntu 20.04 分别是 硬件网络连接方式OSip虚拟机sEUC i5 7250U 16Gwifiwin1010.0.1.223wsl2 - 随机ipMineFine S500 R7 5800H 64G网线Zorin OS 16.2 (Ubuntu 20.04 LTS)10.0.1.198vm1 - 10.0.1.156 …

统计信号处理基础 习题解答6-14

题目&#xff1a; 噪声过程由IID零均值&#xff0c;PDF为 的随机变量组成&#xff0c;其中0<ε<1 。这样的PDF成为高斯混合PDF&#xff0c;它用来模拟 具有方差为 的高斯噪声以及剩余的服从方差 的高斯噪声。一般 &#xff0c;且ε≪1 &#xff0c;所以具有方差为 的背…

[Java安全]—Tomcat反序列化注入回显内存马

前言 在之前学的tomcat filter、listener、servlet等内存马中&#xff0c;其实并不算真正意义上的内存马&#xff0c;因为Web服务器在编译jsp文件时生成了对应的class文件&#xff0c;因此进行了文件落地。 所以本篇主要是针对于反序列化进行内存马注入来达到无文件落地的目的…

[附源码]计算机毕业设计JAVA学生信息管理系统

[附源码]计算机毕业设计JAVA学生信息管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

交流转直流LED驱动芯片 MT7930 SOP8

隔离LED驱动ic芯片 MT7930 SOP8 交流转直流LED驱动芯片 MT7930的描述&#xff1a; MT7930是一个单级、高功率因数&#xff0c;源边控制交流转直流LED驱动芯片。只需极少的外围器件感应源边的电学信息&#xff0c;就可以精确地调制LED电流&#xff0c;而不需要光耦及副边感应器件…

5.javase_循环语句

一.for循环语句 (1)for循环语句 1.1 for循环语句格式&#xff1a; for(初始化语句a;条件判断语句b;条件控制语句c) { 循环体语句d; } 1.2 for循环语句范例&#xff1a; for (int i 1; i < 5; i 1) { System.out.println(“HelloWorld”); } 1.3 for循环语句执行顺序 (2)…

6.每天进步一点点---Python爬虫urllib库

文章未完成待续 urllib 库是 Python 内置的一个 HTTP 请求库。在 Python 2.x 中&#xff0c;是由 urllib 和 urllib2 两 个库来实现请求发送的&#xff0c;在 Python 3.x 中&#xff0c;这两个库已经合并到一起&#xff0c;统一为 urllib 了。 urllib 库由四个模块组成。 re…

LeetCode 69. x 的平方根

&#x1f308;&#x1f308;&#x1f604;&#x1f604; 欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 69. x 的平方根 &#xff0c;做好准备了么&#xff0c;那么开始吧。 &#x1f332;&#x1f332;&#x1f434;&#x1f434; 一、题目名称 69. x 的平方根…

Git全套,从简到细

Git DravenGit一、git工具引入二、git本地工具2.1、下载2.2、使用2.3、修改2.4、查看历史版本2.5、回退历史版本2.6、起死回生三、git远程仓库3.1、使用gitee3.2、配置本地仓库参数3.3、查看gitee仓库3.4、修改后推送四、git两人协作-非冲突小智小杨五、git两人协作-冲突六、gi…

搜索与图论-BFS

文章目录一、BFS1. BFS 简介2. BFS 的基本思想3. BFS 的实现步骤4. BFS 的实际演示二、BFS 例题——走迷宫具体实现1. 样例演示2. 实现思路3. 代码注解4. 实现代码三、BFS 例题——八数码具体实现1. 实现思路2. 代码注解3. 实现代码一、BFS BFS 的关键点是状态的选取和标记。 …

iwebsec靶场 SQL注入漏洞通关笔记13-二次注入

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…

力扣(LeetCode)133. 克隆图(C++)

dfs哈希表图 先深搜建立所有点&#xff0c;加入哈希表。再遍历哈希表&#xff0c;按照拷贝前后的结点&#xff0c;拷贝边。最后返回某一结点&#xff0c;即为所求。 class Solution { public:unordered_map<Node*,Node*> mp;Node* cloneGraph(Node* node) {if(!node) r…

UNPV2 学习:Pipes and FIFOs 学习记录

命名管道 fifo 的特点 特点描述 打破了匿名管道只能在父子进程间使用的限制&#xff0c;可以在无亲缘关系的进程之间使用同一个 fifo未指定 NONBLOCK 参数 open fifo 时可能会 block&#xff0c;不当的编码可能会导致进程死锁当请求读超过 fifo 中现有数据大小的数据时&#…