Maven依赖
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
<spring-io.version>Cairo-SR7</spring-io.version>
</properties>
</dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>${spring-io.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springcloud
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.redis.host=localhost
spring.redis.password=
logging.level.root=debug
sql文件 放在resources目录下
schema.sql
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for ClientDetails
-- ----------------------------
DROP TABLE IF EXISTS `ClientDetails`;
CREATE TABLE `ClientDetails` (
`appId` varchar(256) NOT NULL,
`resourceIds` varchar(256) DEFAULT NULL,
`appSecret` varchar(256) DEFAULT NULL,
`scope` varchar(256) DEFAULT NULL,
`grantTypes` varchar(256) DEFAULT NULL,
`redirectUrl` varchar(256) DEFAULT NULL,
`authorities` varchar(256) DEFAULT NULL,
`access_token_validity` int(11) DEFAULT NULL,
`refresh_token_validity` int(11) DEFAULT NULL,
`additionalInformation` varchar(4096) DEFAULT NULL,
`autoApproveScopes` varchar(256) DEFAULT NULL,
PRIMARY KEY (`appId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token` (
`token_id` varchar(256) DEFAULT NULL COMMENT 'MD5加密的access_token值',
`token` blob COMMENT 'OAuth2AccessToken.java对象序列化后的二进制数据',
`authentication_id` varchar(256) NOT NULL COMMENT 'MD5加密的username, client_id, scope',
`user_name` varchar(256) DEFAULT NULL COMMENT '登录的用户名',
`client_id` varchar(256) DEFAULT NULL COMMENT '客户端id',
`authentication` blob COMMENT 'OAuth2Authentication.java对象序列化后的二进制数据',
`refresh_token` varchar(256) DEFAULT NULL COMMENT 'MD5加密的refresh_token值',
PRIMARY KEY (`authentication_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_approvals
-- ----------------------------
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals` (
`userId` varchar(255) DEFAULT '' COMMENT '登录的用户名',
`clientId` varchar(255) DEFAULT NULL COMMENT '客户端id',
`scope` varchar(255) DEFAULT NULL COMMENT '申请的权限',
`status` varchar(10) DEFAULT NULL COMMENT '状态(Approve/Deny)',
`expiresAt` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '过期时间',
`lastModifiedAt` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'lastModifiedAt'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_client_details
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(256) NOT NULL COMMENT '客户端id',
`resource_ids` varchar(256) DEFAULT NULL COMMENT '资源id集合,多个资源时使用逗号f分隔',
`client_secret` varchar(256) DEFAULT NULL COMMENT '客户端秘钥',
`scope` varchar(256) DEFAULT NULL COMMENT '客户端盛情的权限范围',
`authorized_grant_types` varchar(256) DEFAULT NULL COMMENT '客户端支持的grant_type',
`web_server_redirect_uri` varchar(256) DEFAULT NULL COMMENT '重定向uri',
`authorities` varchar(256) DEFAULT NULL COMMENT '客户端所拥有的spring security的权限值,多个使用逗号分隔',
`access_token_validity` int(11) DEFAULT NULL COMMENT 'f访问令牌有效s时间值,单位秒',
`refresh_token_validity` int(11) DEFAULT NULL COMMENT '更新令牌有效时间值,单位秒',
`additional_information` varchar(4096) DEFAULT NULL COMMENT '预留字段',
`autoapprove` varchar(256) DEFAULT NULL COMMENT '用户是否自动approval操作',
PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_client_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token` (
`token_id` varchar(256) DEFAULT NULL COMMENT 'MD5加密的access_token值',
`token` blob COMMENT 'OAuth2AccessToken.javad对象序列化后的二进制数据',
`authentication_id` varchar(256) NOT NULL COMMENT 'MD5加密的username,client_id,scope',
`user_name` varchar(256) DEFAULT NULL COMMENT '登录的用户名',
`client_id` varchar(256) DEFAULT NULL COMMENT '客户端Id',
PRIMARY KEY (`authentication_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_code
-- ----------------------------
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code` (
`code` varchar(256) DEFAULT NULL COMMENT '授权码未MD5加密',
`authentication` blob COMMENT 'AuthorizationRequestHolder.java对象序列化后的二进制数据'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for oauth_refresh_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token` (
`token_id` varchar(256) DEFAULT NULL COMMENT 'MD5加密的refresh_token的值',
`token` blob COMMENT 'OAuth2RefreshToken.java对象序列化后的二进制数据',
`authentication` blob COMMENT 'OAuth2Authentication.java对象序列化后的二进制数据'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
data.sql
INSERT INTO `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 ('qull', NULL, '$2a$10$tAF2RC0UfUyM/b1jylox5u50i4cyEG2fodkG38SZOqX7DtDew5Iy.', 'read,write', 'authorization_code', 'http://www.baidu.com', 'ROLE_CLIENT', NULL, NULL, NULL, NULL);
OAuth2AuthorizationServer授权服务器
//授权服务器配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
@Bean("jdbcTokenStore")
public JdbcTokenStore getJdbcTokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
public JdbcAuthorizationCodeServices jdbcAuthorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Bean
public JdbcApprovalStore jdbcApprovalStore() {
return new JdbcApprovalStore(dataSource);
}
@Bean
public JdbcClientTokenServices jdbcClientTokenServices() {
return new JdbcClientTokenServices(dataSource);
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
/**
* 定义客户端详细信息服务的配置器。客户端详细信息可以被初始化,或者可以直接引用一个现有的存储
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
}
/**
* 配置令牌端点的安全约束
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()")
.allowFormAuthenticationForClients();
}
/**
* 配置授权以及令牌的访问端点和令牌服务(配置令牌的签名与存储方式)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(getJdbcTokenStore())
.authorizationCodeServices(jdbcAuthorizationCodeServices())
.approvalStore(jdbcApprovalStore())
.authenticationManager(authenticationManager);
}
}
OAuth2ResourceServer资源服务器
//资源服务配置
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**");
}
}
SercurityConfig 安全
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("qull").password(passwordEncoder().encode("qull")).roles("USER");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin();
}
}