OAuth2是一种授权方法,用于通过HTTP协议提供对受保护资源的访问。首先,OAuth2使第三方应用程序能够获得对HTTP服务的有限访问权限,然后通过资源所有者和HTTP服务之间的批准交互来让第三方应用程序代表资源所有者获取访问权限。
oauth2认证流程
创建oauth_client_details表
-- ------------------------------ Table structure for oauth_client_details-- ----------------------------DROP TABLE IF EXISTS `oauth_client_details`;CREATE TABLE `oauth_client_details` ( `client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户端标 识', `resource_ids` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '接入资源列表', `client_secret` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '客户端秘钥', `scope` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `authorized_grant_types` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `web_server_redirect_uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `authorities` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `access_token_validity` int DEFAULT NULL, `refresh_token_validity` int DEFAULT NULL, `additional_information` longtext CHARACTER SET utf8 COLLATE utf8_general_ci, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `archived` tinyint DEFAULT NULL, `trusted` tinyint DEFAULT NULL, `autoapprove` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, PRIMARY KEY (`client_id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='接入客户端信息';
创建oauth_code表
-- ------------------------------ Table structure for oauth_code-- ----------------------------DROP TABLE IF EXISTS `oauth_code`;CREATE TABLE `oauth_code` ( `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `authentication` blob, KEY `code_index` (`code`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;
创建一个父maven工程,并引入依赖
<?xml version="1.0" encoding="UTF-8"?> 4.0.0 tjw cloud-oauth2 pom 1.0-SNAPSHOT auth-server order-a org.springframework.boot spring-boot-starter-parent 2.2.4.RELEASE 1.8 Hoxton.SR1 org.thymeleaf.extras thymeleaf-extras-springsecurity5 3.0.4.RELEASE org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java runtime org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-oauth2 org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import
创建授权服务器
application.yml
server: port: 8081 servlet: context-path: /authspring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3305/item?serverTimezone=UTC username: root password: 123456 main: #当遇到同样名字的bean时,是否允许覆盖注册 allow-bean-definition-overriding: true
@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired ClientDetailsService clientDetailsService; @Autowired AuthenticationManager authenticationManager; @Autowired AuthorizationCodeServices authorizationCodeServices; @Autowired TokenStore tokenStore; @Autowired JwtAccessTokenConverter jwtAccessTokenConverter; @Autowired PasswordEncoder passwordEncoder;// @Bean// public AuthorizationCodeServices authorizationCodeServices() { // return new InMemoryAuthorizationCodeServices();// }//基于数据库的授权码服务 @Bean public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) { return new JdbcAuthorizationCodeServices(dataSource); }//localhost:8081/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com // 令牌管理服务 @Bean public AuthorizationServerTokenServices tokenService() { DefaultTokenServices service=new DefaultTokenServices(); service.setClientDetailsService(clientDetailsService); service.setSupportRefreshToken(true); service.setTokenStore(tokenStore); // jwt令牌配置 TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter)); service.setTokenEnhancer(tokenEnhancerChain); service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时 service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天 return service; return service; } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { super.configure(security); security.tokenKeyAccess("permitAll()") .checkTokenAccess("permitAll()") .allowFormAuthenticationForClients(); } // 重写ClientDetailsService,将客户端的信息存储到数据库 @Bean public ClientDetailsService clientDetailsService(DataSource dataSource){ JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource); jdbcClientDetailsService.setPasswordEncoder(passwordEncoder); return jdbcClientDetailsService; } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientDetailsService); //基于内存// clients.inMemory()// .withClient("c1")//client_id// .secret(new BCryptPasswordEncoder().encode("secret"))// .resourceIds("res1")// .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")//该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials// .scopes("all")//允许的授权范围// .autoApprove(false)// //加上验证回调地址// .redirectUris("http://www.baidu.com"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .authorizationCodeServices(authorizationCodeServices) .tokenServices(tokenService()) .allowedTokenEndpointRequestMethods(HttpMethod.POST); }}
属性
clientId - (必需)客户端ID。
secret - (可信客户端所需)客户端密钥(可选)。
scope - 客户受限的范围。如果范围未定义或为空(默认值),则客户端不受范围限制。
authorizedGrantTypes - 授权客户端使用的授权类型。默认值为空。
authorities - 授予客户的权限(常规Spring Security权限)。
redirectUris - 将用户代理重定向到客户端的重定向端点。它必须是绝对URL。
创建资源服务器
@Configuration@EnableResourceServer@EnableGlobalMethodSecurity(prePostEnabled = true)public class ResourceServerConfig extends ResourceServerConfigurerAdapter { public static final String RESOURCE_ID = "res1"; @Autowired TokenStore tokenStore; public ResourceServerTokenServices tokenServices(){ RemoteTokenServices services = new RemoteTokenServices(); services.setCheckTokenEndpointUrl("http://localhost:8081/auth/oauth/check_token"); services.setClientId("c1"); services.setClientSecret("secret"); return services; } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId(RESOURCE_ID) // 使用jwt令牌进行校验 .tokenStore(tokenStore) //验证令牌服务// .tokenServices(tokenServices()) .stateless(true); } @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/**")// .hasAnyAuthority("all","ROLE_ADMIN") .access("#oauth2.hasScope('ROLE_ADMIN')") .and().csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); }}
资源
@RestControllerpublic class OrderController { @GetMapping("/r1") @PreAuthorize("hasAnyAuthority('p1')") public String r1(){ return "资源1"; }}
测试
浏览器输入
localhost:8081/auth/oauth/authorize?client_id=c1&response_type=code&scope=ROLE_ADMIN&redirect_uri=http://www.baidu.com
过浏览器访问上面的URL地址,它将展现一个登录页面。提供用户名和密码。
点击authorize
这样就拿到了授权码,使用授权码来生成JWT token
使用token,来访问资源
留言与评论(共有 0 条评论) “” |