介绍
Spring Security OAuth2 是一个在 Spring Security 框架基础上构建的 OAuth2 授权服务器和资源服务器的扩展库。它提供了一套功能强大的工具和组件,用于实现 OAuth2 协议中的授权流程、令牌管理和访问控制。
Git地址:yunfeng-boot3-sercurity: Spring Security OAuth2 统一登录(授权码模式)
版本
SpringBoot 2.5.6
OAuth2重要角色
- Authorization Server : 授权服务器。
- Resource Server: 资源服务器。举例针对微服务里面各个业务子系统:用户系统、商家系统、商品系统、订单系统等等。
- Client:客户端:浏览器、APP、小程序等等
具体实现
OAuth2 有多种授权模式。本实例中,使用授权码模式 + 授权服务器,来实现用户的认证。
主要接口:
- 获取授权码:http://localhost:8080/auth/oauth/authorize?response_type=code&client_id=hello&redirect_uri=http://localhost:8080&scope=all
- 获取token:http://localhost:8080/auth/oauth/token
首先,创建一个SpringBoot应用,作为授权服务器。集成SpringBoot 2.5.6 + MySQL + Spring Security + Redis。
- 配置AuthorizationServerConfigurerAdapter.
继承AuthorizationServerConfigurerAdapter 主要是针对授权服务器进行自定义配置。
- 配置token的接口权限,允许进行客户端授权。每个token都是跟某一个客户端进行关联的。所以MySQL里面
需要增加一张表,并配置好需要授权的客户端记录.
表结构如下:
CREATE TABLE `oauth_client_details` (
`client_id` varchar(256) COMMENT '客户端ID',
`resource_ids` varchar(256),
`client_secret` varchar(256) COMMENT '客户端密钥',
`scope` varchar(256),
`authorized_grant_types` varchar(256) COMMENT '授权类型',
`web_server_redirect_uri` varchar(256),
`authorities` varchar(256),
`access_token_validity` int(11) COMMENT 'access_token的有效时间',
`refresh_token_validity` int(11) COMMENT 'refresh_token的有效时间',
`additional_information` varchar(4096),
`autoapprove` varchar(256) COMMENT '是否允许自动授权',
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `weef_iot_edge_shaoyifu`.`oauth_client_details` (`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`) VALUES ('hello', 'order-resource', '$2a$10$Kc3YXJdKpWEtLFD.xBSlFO5.OD94MZ7zWdl9CiQ5OGlYvSuvM8qoi', 'all', 'authorization_code,password', 'http://localhost:8080', NULL, 3600, NULL, NULL, 'true');
授权服务器代码如下:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Resourceprivate DataSource dataSource;@Resourceprivate RedisConnectionFactory redisConnectionFactory;private final static String TOKEN_STORE_PREFIX = "yf-token-store";@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {// 开启/oauth/token_key验证端口无权限访问security.tokenKeyAccess("permitAll()")// 开启/oauth/check_token验证端口认证权限访问.checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(clientDetailsService());}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);tokenStore.setPrefix(TOKEN_STORE_PREFIX);endpoints.tokenStore(tokenStore);}public ClientDetailsService clientDetailsService() {return new JdbcClientDetailsService(dataSource);}}
- 配置WebSecurityConfigurerAdapter
继承WebSecurityConfigurerAdapter,来实现用户信息的配置。这个简化实现。内置了用户名和密码。通过这个类,可以扩展到使用MySQL来时实现,用户名和密码的校验。
同时,针对Spring Security 内置登录页面。也可以通过配置这个类,实现自定义的登录页面。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("zhangsan").password(passwordEncoder().encode("123456")).roles("ADMIN").and().passwordEncoder(passwordEncoder());System.out.println(passwordEncoder().encode("123456"));}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}
- 获取code:通过浏览器访问:http://localhost:8080/auth/oauth/authorize?response_type=code&client_id=hello&redirect_uri=http://localhost:8080&scope=all
登录之后,可以拿到code
- 调用获取token接口: