授權得客戶端信息、授權碼信息全都存在數據庫
1.建表
官方給了個sql文件:https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
create table oauth_client_details ( client_id VARCHAR(128) PRIMARY KEY, resource_ids VARCHAR(128), client_secret VARCHAR(128), scope VARCHAR(128), authorized_grant_types VARCHAR(128), web_server_redirect_uri VARCHAR(128), authorities VARCHAR(128), access_token_validity INTEGER, refresh_token_validity INTEGER, additional_information VARCHAR(4096), autoapprove VARCHAR(128) ); create table oauth_client_token ( token_id VARCHAR(128), token BLOB, authentication_id VARCHAR(128) PRIMARY KEY, user_name VARCHAR(128), client_id VARCHAR(128) ); create table oauth_access_token ( token_id VARCHAR(128), token BLOB, authentication_id VARCHAR(128) PRIMARY KEY, user_name VARCHAR(128), client_id VARCHAR(128), authentication BLOB, refresh_token VARCHAR(128) ); create table oauth_refresh_token ( token_id VARCHAR(128), token BLOB, authentication BLOB ); create table oauth_code ( code VARCHAR(128), authentication BLOB ); create table oauth_approvals ( userId VARCHAR(128), clientId VARCHAR(128), scope VARCHAR(128), status VARCHAR(10), expiresAt TIMESTAMP, lastModifiedAt TIMESTAMP );
//造點測試數據
/*
INSERT INTO `oauth_client_details` VALUES ('client1', 'resource1', '$2a$10$YEpRG0cFXz5yfC/lKoCHJ.83r/K3vaXLas5zCeLc.EJsQ/gL5Jvum', 'scope1,scope2', 'authorization_code,password,client_credentials,implicit,refresh_token', 'http://www.baidu.com', null, '300', '1500', null, 'false');*/
2.配置數據源 yml里配置后注入到clientDetailService
server: port: 8001 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root url: mysql://192.168.3.158:3306/test?&useUnicode=true&characterEncoding=utf-8
3.配置clientDetailService
@Autowired private DataSource dataSource; //配置客戶端 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //配置客戶端存儲到db 代替原來得內存模式 JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); clientDetailsService.setPasswordEncoder(passwordEncoder); clients.withClientDetails(clientDetailsService); }
4.授權碼存到數據庫
@Configuration public class TokenConfig { @Autowired private DataSource dataSource; //配置token的存儲方法 @Bean public TokenStore tokenStore() { //配置token存儲在數據庫 return new JdbcTokenStore(dataSource); } }
//配置token管理服務 @Bean public AuthorizationServerTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setClientDetailsService(clientDetailsService); defaultTokenServices.setSupportRefreshToken(true); //配置token的存儲方法 defaultTokenServices.setTokenStore(tokenStore); defaultTokenServices.setAccessTokenValiditySeconds(300); defaultTokenServices.setRefreshTokenValiditySeconds(1500); return defaultTokenServices; }
以上完整代碼:
AuthorizationServerConfig
@Configuration //開啟oauth2,auth server模式 @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired private DataSource dataSource; //配置客戶端 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //配置客戶端存儲到db JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); clientDetailsService.setPasswordEncoder(passwordEncoder); clients.withClientDetails(clientDetailsService); } @Autowired private ClientDetailsService clientDetailsService; @Autowired private TokenStore tokenStore; //配置token管理服務 @Bean public AuthorizationServerTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setClientDetailsService(clientDetailsService); defaultTokenServices.setSupportRefreshToken(true); //配置token的存儲方法 defaultTokenServices.setTokenStore(tokenStore); defaultTokenServices.setAccessTokenValiditySeconds(300); defaultTokenServices.setRefreshTokenValiditySeconds(1500); return defaultTokenServices; } //密碼模式才需要配置,認證管理器 @Autowired private AuthenticationManager authenticationManager; //把上面的各個組件組合在一起 @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager)//認證管理器 //配置授權碼存儲到db .authorizationCodeServices(new JdbcAuthorizationCodeServices(dataSource))//授權碼管理 .tokenServices(tokenServices())//token管理 .allowedTokenEndpointRequestMethods(HttpMethod.POST); } //配置哪些接口可以被訪問 @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()")///oauth/token_key公開 .checkTokenAccess("permitAll()")///oauth/check_token公開 .allowFormAuthenticationForClients();//允許表單認證 } }
TokenConfig
@Configuration public class TokenConfig { @Autowired private DataSource dataSource; //配置token的存儲方法 @Bean public TokenStore tokenStore() { //配置token存儲在內存中,這種是普通token,每次都需要遠程校驗,性能較差 return new JdbcTokenStore(dataSource); } }
WebSecurityConfig
@Configuration @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } //密碼模式才需要配置,認證管理器 @Bean @Override protected AuthenticationManager authenticationManager() throws Exception { return super.authenticationManager(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .anyRequest().permitAll() .and() .formLogin() .and() .logout(); } @Bean public UserDetailsService userDetailsService() { return s -> { if ("admin".equals(s) || "user".equals(s)) { return new MyUserDetails(s, passwordEncoder().encode(s), s); } return null; }; } }
驗證:
//授權碼模式
//瀏覽器訪問
http://127.0.0.1:8001/oauth/authorize?client_id=client1&response_type=code&scope=scope1&redirect_uri=http://www.baidu.com
授權碼也存入了數據庫:
postman申請令牌
已經存入了數據庫
驗證令牌