快速集成OAuth授权服务

概念

OAuth的实现思路:OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。“客户端"不能直接登录"服务提供商”,只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。 "客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。

为了使资源访问安全,设置给用户携带token访问资源。达到的效果如下面流程图:

  • 流程图
    2.使用账号密码到授权服务获取token
    3.携带token重新请求资源,返回资源信息

实践

授权服务

创建授权服务,用于生成token、验证token,首先创建Springboot项目,然后进行如下步骤:

  • 增加maven依赖
  • 配置数据库地址、增加token的数据库存储配置
  • 初始化数据库
步骤1:添加maven依赖

引入oauth2mysql依赖,mysql用来存储和配置token

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- 实现对 Spring MVC 的自动配置 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> <version>2.2.5.RELEASE</version></dependency><!-- 实现对数据库连接池的自动化配置 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.18</version></dependency> 
步骤2:添加主要配置
  • application.yml

application.yml增加数据库配置信息

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=falseusername: adminpassword: qwe234 
  • OAuth2AuthorizationServerConfig

设置token存储与配置,设置使用 JdbcTokenStore和 ClientDetailsService

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate DataSource dataSource;@Beanpublic TokenStore jdbcTokenStore(){return new JdbcTokenStore(dataSource);}// token存储到数据库中@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).tokenStore(jdbcTokenStore());}@Overridepublic void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {oauthServer.checkTokenAccess("isAuthenticated()");}@Beanpublic ClientDetailsService jdbcClientDetailsService() {return new JdbcClientDetailsService(dataSource);}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(jdbcClientDetailsService());}

} 
  • SecurityConfig

配置使用jdbcAuthentication认证

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Override@Bean(name = BeanIds.AUTHENTICATION_MANAGER)public AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Beanpublic static NoOpPasswordEncoder passwordEncoder() {return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication().dataSource(dataSource);}

} 
步骤3:初始化数据库
-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token`(`token_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`token` mediumblob NULL,`authentication_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`authentication` mediumblob NULL,`refresh_token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_approvals
-- ----------------------------
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals`(`userId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`clientId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`status` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`expiresAt` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP,`lastModifiedAt` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`(`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`resource_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`client_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`authorized_grant_types` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`web_server_redirect_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`authorities` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`access_token_validity` int(0) NULL DEFAULT NULL,`refresh_token_validity` int(0) NULL DEFAULT NULL,`additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`autoapprove` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES ('tokendemo', NULL, '1qa233', 'read_userinfo,read_contacts', 'password,refresh_token,authorization_code', 'http://127.0.0.1:8080/login', NULL, 3600, 864000, NULL, '1');

-- ----------------------------
-- Table structure for oauth_client_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token`(`token_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`token` mediumblob NULL,`authentication_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_code
-- ----------------------------
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code`(`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`authentication` mediumblob NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for oauth_refresh_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token`(`token_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`token` mediumblob NULL,`authentication` mediumblob NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 
资源服务

资源服务改造,主要包括如下几步:

  • 添加maven依赖
  • 增加OAuth2.0配置信息
  • 设置授权服务地址
  • 登录接口demo
步骤1:添加maven依赖

添加maven依赖

<dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.1.2.RELEASE</version>
</dependency> 
步骤2:增加OAuth2.0配置信息
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests()// 设置 /login 无需权限访问.antMatchers("/login").permitAll()// 设置其它请求,需要认证后访问.anyRequest().authenticated();}

} 
步骤3:设置授权服务地址
security:oauth2:# OAuth2 Client 配置,对应 OAuth2ClientProperties 类client:client-id: tokendemoclient-secret: 1qa233user-authorization-uri: http://127.0.0.1:8082/oauth/authorize # 获取用户的授权码地址access-token-uri: http://127.0.0.1:8082/oauth/token # 获取访问令牌的地址# OAuth2 Resource 配置,对应 ResourceServerProperties 类resource:client-id: tokendemouser-info-uri: http://127.0.0.1:8082/authorize # 获取用户的授权码地址token-info-uri: http://127.0.0.1:8082/oauth/check_token# 获取用户的授权码验证地址 
步骤4:登录接口demo

调用登录接口时,使用用户名/密码去授权服务获取token,后面可以用这个token访问资源服务的其他接口

@RestController
@RequestMapping("/login")
public class LoginController {@Value("${security.oauth2.client.access-token-uri}")private String accessTokenUri;@Value("${security.oauth2.client.client-id}")private String clientId;@Value("${security.oauth2.client.client-secret}")private String clientSecret;@PostMappingpublic OAuth2AccessToken login(@RequestParam("username") String username, @RequestParam("password") String password) {ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();resourceDetails.setAccessTokenUri(accessTokenUri);resourceDetails.setClientId(clientId);resourceDetails.setClientSecret(clientSecret);resourceDetails.setUsername(username);resourceDetails.setPassword(password);// 请求授权服务,获取tokenOAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);restTemplate.setAccessTokenProvider(new ResourceOwnerPasswordAccessTokenProvider());return restTemplate.getAccessToken();}

} 
验证
  • login获取token

请求login接口可以看到返回值如下:

  • 访问资源

携带token访问资源如下:

总结

src=“https://img-blog.csdnimg.cn/img_convert/9fb3040baca4fe1539f0607951f5073c.png” style=“margin: auto” />

总结

以上就是快速集成oauth,简单的使用了mysql作为存储,正常开发推荐使用redis存储,redis的过期机制与token过期更加契合。## 网络安全工程师(白帽子)企业级学习路线

第一阶段:安全基础(入门)

img

第二阶段:Web渗透(初级网安工程师)

img

第三阶段:进阶部分(中级网络安全工程师)

img

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

学习资源分享

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值