Springboot利用Security做OAuth2授权验证
创始人
2024-03-16 04:59:56
0

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

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

第一步 添加依赖

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

        org.springframework.bootspring-boot-starter-weborg.springframework.cloudspring-cloud-starter-securityorg.springframework.cloudspring-cloud-starter-oauth2

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

引入数据库依赖

        org.springframework.bootspring-boot-starter-data-jpamysqlmysql-connector-java

第二步 添加代码

1 实现UserDetailsService,获取用户

@Service
public class MyUserDetailsService implements UserDetailsService {@Resourceprivate UserService userService;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名获取用户,并验证用户是否有效及权限//从数据库中获取用户TUser user = userService.findByUsername(username);if (user == null) {throw new UsernameNotFoundException("用户不存在");}Set 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 {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}}

3 添加AuthorizationServerConfigurerAdapter

@Configuration
@EnableAuthorizationServer
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {//验证管理器@Resourceprivate AuthenticationManager authenticationManager;//获取用户,自己实现获取用户的相关功能@Resourceprivate MyUserDetailsService userService;//数据库配置@Resourceprivate DataSource dataSource;/*** 自定义授权服务配置*/@Overridepublic 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*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {//自定义客户端配置clients.withClientDetails(clientDetails());}//从数据库中获取客户端的配置public ClientDetailsService clientDetails() {return new JdbcClientDetailsService(dataSource);}/*** 自定义授权令牌端点的安全约束* @param security*/@Overridepublic 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/Shanghaiusername: rootpassword: "123456"driver-class-name: com.mysql.cj.jdbc.Driverjpa:show-sql: trueserver:port: 8080

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

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

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

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...