Related off from Li Gebo: https://funtl.com/zh/spring-security-oauth2/ (paper record only their own learning record, that's not in detail, you can watch Li Gebo off)
The authentication server and server resources pom.xml configuration (Li Gebo guest is tk.mybatis I use the spring jpa)
<dependencies> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <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> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
Authentication Server:
apllication.yml:
Server: Port: 9999 the Spring: the DataSource: Driver-class-name: com.mysql.cj.jdbc.Driver url: (own database) username: (account) password: (password) Hikari: Minimum-IDLE: 5 IDLE- timeout: 600000 maximum-the pool-size: 10 Auto-the commit: to true the pool-name: MyHikariCP max-Lifetime: 1800000 Connection-timeout: 30000 Connection-Test-Query: the SELECT. 1
Authentication Server configuration:
Certification customer service side:
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration the extends AuthorizationServerConfigurerAdapter { @Bean @Primary @ConfigurationProperties (prefix = "spring.datasource") public the dataSource the DataSource () { // configuration data source (HikariCP connection pool is used), or more annotation data is designated source, otherwise there is a conflict return DataSourceBuilder.create () Build ();. } @Bean public tokenStore tokenStore () { // JDBC-based implementation, the data saved to the token return new new JdbcTokenStore (the dataSource ()); } @Bean public jdbcClientDetails ClientDetailsService () { // JDBC-based implementation, it must be configured in the client information database return new JdbcClientDetailsService(dataSource()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { // 设置令牌 endpoints.tokenStore(tokenStore()); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // 读取客户端配置 clients.withClientDetails(jdbcClientDetails()); } }
Authorized customer service side:
@Configuration
public class UserDetailsServiceConfiguration implements UserDetailsService {
@Autowired
private TbUserService tbUserService;
@Autowired
private TbPermissionService tbPermissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
TbUser tbUser = tbUserService.findByUsername(username);
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
if (tbUser != null) {
// 获取用户授权
List<TbPermission> tbPermissions = tbPermissionService.selectByUserId(tbUser.getId());
// 声明用户授权
tbPermissions.forEach(tbPermission -> {
if (tbPermission != null && tbPermission.getEnname() != null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(tbPermission.getEnname());
grantedAuthorities.add(grantedAuthority);
}
});
}
return new User(tbUser.getUsername(), tbUser.getPassword(), grantedAuthorities);
}
}
Security Configuration:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsServiceConfiguration userDetailsServiceConfiguration; @Bean public BCryptPasswordEncoder passwordEncoder() { // 设置默认的加密方式 return new BCryptPasswordEncoder(); } @Bean @Override public UserDetailsService userDetailsService(){ return userDetailsServiceConfiguration; } @Override void the configure protected (AuthenticationManagerBuilder auth) throws Exception { // use custom authentication and authorization auth.userDetailsService (userDetailsService ()); } @Override public void the configure (WebSecurity Web) { check_token // will be exposed to otherwise access server resources Times 403 error web.ignoring () antMatchers ( "/ OAuth / check_token");. } }
Obtaining user information and rights information and code directory:
@Repository public interface TbPermissionRepository extends JpaRepository<TbPermission,Long> { @Query(value = "SELECT\n" + " p.*\n" + "FROM\n" + " tb_user AS u\n" + " LEFT JOIN tb_user_role AS ur\n" + " ON u.id = ur.user_id\n" + " LEFT JOIN tb_role AS r\n" + " ON r.id = ur.role_id\n" + " LEFT JOIN tb_role_permission AS rp\n" + " ON r.id = rp.role_id\n" + " LEFT JOIN tb_permission AS p\n" + " ON p.id = rp.permission_id\n" + "WHERE u.id = ?1",nativeQuery = true) public List<TbPermission> selectByUserId(Long id); }
@Repository public interface TbUserRepository extends JpaRepository<TbUser,Long> { @Query(value = "select * from tb_user where username = ?1",nativeQuery = true) public TbUser findByUsername(String username); }
@Service public class TbPermissionService{ @Autowired private TbPermissionRepository tbPermissionRepository; public List<TbPermission> selectByUserId(Long id){ List<TbPermission> tbPermissions = tbPermissionRepository.selectByUserId(id); return tbPermissions; } }
@Service public class TbUserService { @Autowired private TbUserRepository tbUserRepository; public TbUser findByUsername(String username){ TbUser byUsername = tbUserRepository.findByUsername(username); return byUsername; } }
Kefuduan Table: oauth_client_details
Acquisition code request address (GET request): http://{you ip}:{you port}/oauth/authorize?client_id=client&response_type=code (client_id为上图中的client_id,成功之后会回调url 为上面的web_server_redicrct_uri)
Acquiring an address token request (POST request :) : HTTP: // Client: Secret you @ {IP}: {Port} you / OAuth / token carries parameters: grant_type (authorization_grant_type of the above figure) code (top code returned )
Resource server:
application.yml:
server: port: 10000 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: (自己的数据库) username: (账号) password: (密码) hikari: minimum-idle: 5 idle-timeout: 600000 maximum-pool-size: 10 auto-commit: true pool-name: MyHikariCP max-lifetime: 1800000 connection-timeout: 30000 connection-test-query: SELECT 1 security: oauth2: client: client-id: client client-secret: secret access-token-uri: http://localhost:9999/oauth/token user-authorization-uri: http://localhost:9999/oauth/authorize resource: token-info-uri: http://localhost:9999/oauth/check_token
Resource server is the normal CRUD and docking Oauth2 authentication and authorization server
@Configuration @EnableResourceServer @EnableGlobalMethodSecurity (= prePostEnabled to true, to true securedEnabled =, = jsr250Enabled to true) public class ResourceServerConfiguration the extends ResourceServerConfigurerAdapter { @Override public void Configure (HttpSecurity HTTP) throws Exception { HTTP .exceptionHandling () .AND () .sessionManagement () .sessionCreationPolicy (SessionCreationPolicy.STATELESS) .AND () .authorizeRequests () // the following is the allocation of resources and authority necessary to protect the path, you need to configure the corresponding part of the authorization and authentication server .antMatchers ( "/"). hasAuthority ( "System ") .antMatchers("/view/**").hasAuthority("SystemContentView") .antMatchers("/insert/**").hasAuthority("SystemContentInsert") .antMatchers("/update/**").hasAuthority("SystemContentUpdate") .antMatchers("/delete/**").hasAuthority("SystemContentDelete"); } }
Sql database-related statements:
jdbc storage token:
CREATE TABLE `clientdetails` ( `appId` varchar(128) 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; CREATE TABLE `oauth_access_token` ( `token_id` varchar(256) DEFAULT NULL, `token` blob, `authentication_id` varchar(128) NOT NULL, `user_name` varchar(256) DEFAULT NULL, `client_id` varchar(256) DEFAULT NULL, `authentication` blob, `refresh_token` varchar(256) DEFAULT NULL, PRIMARY KEY (`authentication_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `oauth_approvals` ( `userId` varchar(256) DEFAULT NULL, `clientId` varchar(256) DEFAULT NULL, `scope` varchar(256) DEFAULT NULL, `status` varchar(10) DEFAULT NULL, `expiresAt` timestamp NULL DEFAULT NULL, `lastModifiedAt` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `oauth_client_details` ( `client_id` varchar(128) NOT NULL, `resource_ids` varchar(256) DEFAULT NULL, `client_secret` varchar(256) DEFAULT NULL, `scope` varchar(256) DEFAULT NULL, `authorized_grant_types` varchar(256) DEFAULT NULL, `web_server_redirect_uri` varchar(256) DEFAULT NULL, `authorities` varchar(256) DEFAULT NULL, `access_token_validity` int(11) DEFAULT NULL, `refresh_token_validity` int(11) DEFAULT NULL, `additional_information` varchar(4096) DEFAULT NULL, `autoapprove` varchar(256) DEFAULT NULL, PRIMARY KEY (`client_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `oauth_client_token` ( `token_id` varchar(256) DEFAULT NULL, `token` blob, `authentication_id` varchar(128) NOT NULL, `user_name` varchar(256) DEFAULT NULL, `client_id` varchar(256) DEFAULT NULL, PRIMARY KEY (`authentication_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `oauth_code` ( `code` varchar(256) DEFAULT NULL, `authentication` blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `oauth_refresh_token` ( `token_id` varchar(256) DEFAULT NULL, `token` blob, `authentication` blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
RBAC:
TABLE `tb_permission` the CREATE ( ` id` BIGINT (20 is) the AUTO_INCREMENT the NOT NULL, `parent_id` BIGINT (20 is) the COMMENT the DEFAULT NULL 'parent rights', ` name` VARCHAR (64) the COMMENT the NOT NULL 'privilege name', `enname` varchar (64) NOT NULL COMMENT 'rights English name', `url` VARCHAR (255) the COMMENT the NOT NULL 'authorized path', ` description` VARCHAR (200 is) the COMMENT the DEFAULT NULL 'Remarks', `created` datetime the NOT NULL, ` datetime the NOT NULL updated`, a PRIMARY KEY ( `id`) ) = 44 is the AUTO_INCREMENT the InnoDB ENGINE = the DEFAULT the CHARSET = UTF8 the COMMENT = 'permission table'; INSERT INTO tb_permission`` ( `id`, parent_id``, `name`,` enname`, url` `,` description`, created` `,` updated`) values (37,0, 'management system', 'system', '/ ', NULL, '2019-04-04 23:22:54','2019-04-04 23:22:56'), (38, 37, 'User Manager', 'SystemUser', '/ Users /', NULL, '2019-04-04 23:25:31', '2019-04-04 23:25:33'), ( 39 and 38, 'the user to view', 'SystemUserView', '', NULL, '2019-04-04 15:30:30', '2019-04-04 15:30:43'), (40,38, 'new users',' SystemUserInsert ',' ', NULL,' 2019-04-04 15:30:31 ',' 2019-04-04 15:30:44 '), (41,38,' edit user ',' SystemUserUpdate ',' ', NULL,' 2019-04-04 15:30:32 ',' 2019-04-04 15:30:45 '), (42,38,' delete user ',' SystemUserDelete ',' ', NULL,' 2019-04-04 15:30:48 ',' 2019-04-04 15:30:45 '); the CREATE TABLE tb_role` `( ` id` BIGINT (20 is) the AUTO_INCREMENT the NOT NULL , `parent_id` bigint (20) the DEFAULT NULL the COMMENT 'parent role' `name` varchar (64) NOT NULL COMMENT ' role name', ` enname` VARCHAR (64-) the NOT NULL the COMMENT 'role English name', `description` VARCHAR (200) NULL the DEFAULT the COMMENT 'Remarks' `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='角色表'; insert into `tb_role`(`id`,`parent_id`,`name`,`enname`,`description`,`created`,`updated`) values (37,0,'超级管理员','admin',NULL,'2019-04-04 23:22:03','2019-04-04 23:22:05'); CREATE TABLE `tb_role_permission` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `role_id` bigint(20) NOT NULL COMMENT '角色 ID', `permission_id` bigint(20) NOT NULL COMMENT '权限 ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 COMMENT='角色权限表'; insert into `tb_role_permission`(`id`,`role_id`,`permission_id`) values (37,37,37), (38,37,38), (39,37,39), (40,37,40), (41,37,41), (42,37,42); CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(64) NOT NULL COMMENT '密码,加密存储', `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号', `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱', `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) USING BTREE, UNIQUE KEY `phone` (`phone`) USING BTREE, UNIQUE KEY `email` (`email`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户表'; insert into `tb_user`(`id`,`username`,`password`,`phone`,`email`,`created`,`updated`) values (37,'admin','$2a$10$9ZhDOBp.sRKat4l14ygu/.LscxrMUcDAfeVOEPiYwbcRkoB09gCmi','15888888888','[email protected]','2019-04-04 23:21:27','2019-04-04 23:21:29'); CREATE TABLE `tb_user_role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL COMMENT '用户 ID', `role_id` bigint(20) NOT NULL COMMENT '角色 ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户角色表'; insert into `tb_user_role`(`id`,`user_id`,`role_id`) values (37,37,37);
Kefuduan table may add a custom table records and related RBAC can also customize record;