ApiBoot Security Oauth

引入 ApiBoot Security Oauth

pom.xml配置文件内添加如下:

  1. <!--ApiBoot Security Oauth-->
  2. <dependency>
  3. <groupId>org.minbox.framework</groupId>
  4. <artifactId>api-boot-starter-security-oauth-jwt</artifactId>
  5. </dependency>

ApiBoot所提供的依赖都不需要添加版本号,但是需要添加版本依赖,具体查看ApiBoot版本依赖

配置参数列表

ApiBoot在整合SpringSecurityOauth2时把配置参数进行了分离,配置列表如下所示:

整合SpringSecurity配置列表

配置名称介绍默认值生效方式
api.boot.security.awaySpringSecurity读取用户的方式,默认为内存方式memoryall
api.boot.security.auth-prefix拦截的接口路径前缀,如:/api/users就会被默认拦截/api/memory/jdbc
api.boot.security.users配置用户列表,具体使用查看内存方式介绍memory
api.boot.security.ignoring-urlsSpring Security所排除的路径,默认排除Swagger、Actuator相关路径前缀/v2/api-docs/swagger-ui.html/swagger-resources/configuration/security/META-INF/resources/webjars//swagger-resources/swagger-resources/configuration/ui/actuator/**memory/jdbc
api.boot.security.enable-default-store-delegate仅在Jdbc方式生效truejdbc

整合Oauth2配置列表

配置名称介绍默认值绑定away
api.boot.oauth.awayOauth存储Token、读取Client信息方式memoryall
api.boot.oauth.cleint-idOauth2 Client IDApiBootmemory
api.boot.oauth.client-secretOauth2 Client SecretApiBootSecretmemory
api.boot.oauth.grant-types客户端授权方式Srtring[]{"password"}memory
api.boot.oauth.scopes客户端作用域String[]{"api"}memory
api.boot.oauth.jwt.enable是否启用JWT格式化AccessTokenfalsememory/jdbc
api.boot.oauth.jwt.sign-key使用JWT格式化AccessToken时的签名ApiBootmemory/jdbc

ApiBoot在整合SpringSecurityOauth2时配置进行了分离,也就意味着我们可以让SpringSecurity读取内存用户、Oauth2将生成的AccessToken存放到数据库,当然反过来也是可以的,相互不影响!!!

内存方式(默认方式)

Spring Security

ApiBoot在整合Spring Security的内存方式时,仅仅需要配置api.boot.security.users用户列表参数即可,就是这么的简单,

配置用户示例如下所示:

  1. api:
  2. boot:
  3. security:
  4. # Spring Security 内存方式用户列表示例
  5. users:
  6. - username: hengboy
  7. password: 123456
  8. - username: apiboot
  9. password: abc321

api.boot.security.users是一个List<SecurityUser>类型的集合,所以这里可以配置多个用户。

Oauth2

如果全部使用默认值的情况话不需要做任何配置!!!

Jdbc方式

前提:项目需要添加数据源依赖。

Spring Security

默认用户表

ApiBoot在整合Spring Security的Jdbc方式时,在使用ApiBoot提供的默认结构用户表时只需要修改api.boot.security.away: jdbc即可,ApiBoot提供的用户表结构如下所示:

  1. CREATE TABLE `api_boot_user_info` (
  2. `UI_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号,主键自增',
  3. `UI_USER_NAME` varchar(30) DEFAULT NULL COMMENT '用户名',
  4. `UI_NICK_NAME` varchar(50) DEFAULT NULL COMMENT '用户昵称',
  5. `UI_PASSWORD` varchar(255) DEFAULT NULL COMMENT '用户密码',
  6. `UI_EMAIL` varchar(30) DEFAULT NULL COMMENT '用户邮箱地址',
  7. `UI_AGE` int(11) DEFAULT NULL COMMENT '用户年龄',
  8. `UI_ADDRESS` varchar(200) DEFAULT NULL COMMENT '用户地址',
  9. `UI_IS_LOCKED` char(1) DEFAULT 'N' COMMENT '是否锁定',
  10. `UI_IS_ENABLED` char(1) DEFAULT 'Y' COMMENT '是否启用',
  11. `UI_STATUS` char(1) DEFAULT 'O' COMMENT 'O:正常,D:已删除',
  12. `UI_CREATE_TIME` timestamp NULL DEFAULT current_timestamp() COMMENT '用户创建时间',
  13. PRIMARY KEY (`UI_ID`)
  14. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='ApiBoot默认的用户信息表';

自定义用户表

如果你的系统已经存在了自定义用户表结构,ApiBoot是支持的,而且很简单就可以完成整合,我们需要先修改api.boot.security.enable-default-store-delegate参数为false,如下所示:

  1. api:
  2. boot:
  3. security:
  4. # Spring Security jdbc方式用户列表示例
  5. enable-default-store-delegate: false
  6. away: jdbc

添加ApiBootStoreDelegate接口实现类,如下所示:

  1. @Component
  2. public class DisableDefaultUserTableStoreDelegate implements ApiBootStoreDelegate {
  3.  
  4. @Autowired
  5. private PasswordEncoder passwordEncoder;
  6.  
  7. /**
  8. * 用户列表示例
  9. * 从该集合内读取用户信息
  10. * 可以使用集合内的用户获取access_token
  11. */
  12. static List<String> users = new ArrayList() {
  13. {
  14. add("api-boot");
  15. add("hengboy");
  16. add("yuqiyu");
  17. }
  18. };
  19.  
  20. /**
  21. * 根据用户名查询用户信息
  22. *
  23. * @param username 用户名
  24. * @return
  25. * @throws UsernameNotFoundException
  26. */
  27. @Override
  28. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  29. if (!users.contains(username)) {
  30. throw new UsernameNotFoundException("用户:" + username + "不存在");
  31. }
  32. return new DisableDefaultUserDetails(username);
  33. }
  34.  
  35. @Data
  36. @AllArgsConstructor
  37. @NoArgsConstructor
  38. class DisableDefaultUserDetails implements UserDetails {
  39. private String username;
  40.  
  41. @Override
  42. public Collection<? extends GrantedAuthority> getAuthorities() {
  43. return new ArrayList() {
  44. {
  45. add((GrantedAuthority) () -> "ROLE_USER");
  46. }
  47. };
  48. }
  49.  
  50. /**
  51. * 示例密码使用123456
  52. *
  53. * @return
  54. */
  55. @Override
  56. public String getPassword() {
  57. return passwordEncoder.encode("123456");
  58. }
  59.  
  60. @Override
  61. public String getUsername() {
  62. return username;
  63. }
  64.  
  65. @Override
  66. public boolean isAccountNonExpired() {
  67. return true;
  68. }
  69.  
  70. @Override
  71. public boolean isAccountNonLocked() {
  72. return true;
  73. }
  74.  
  75. @Override
  76. public boolean isCredentialsNonExpired() {
  77. return true;
  78. }
  79.  
  80. @Override
  81. public boolean isEnabled() {
  82. return true;
  83. }
  84. }
  85. }

根据上面代码示例,我们可以通过users用户列表进行访问获取access_token

Oauth2

创建Oauth所需表结构

Oauth2如果使用Jdbc方式进行存储access_tokenclient_details时,需要在数据库内初始化Oauth2所需相关表结构,oauth-mysql.sql

添加客户端数据

初始化Oauth2表结构后,需要向oauth_client_details表内添加一个客户端信息,下面是对应ApiBoot Security Oauth配置信息的数据初始化,如下所示:

  1. INSERT INTO `oauth_client_details` VALUES ('ApiBoot','api','$2a$10$M5t8t1fHatAj949RCHHB/.j1mrNAbxIz.mOYJQbMCcSPwnBMJLmMK','api','password',NULL,NULL,7200,7200,NULL,NULL);

AppSecret加密方式统一使用BCryptPasswordEncoder,数据初始化时需要注意。

在上面memory/jdbc两种方式已经配置完成,接下来我们就可以获取access_token

获取AccessToken

通过CURL获取

  1. ~ curl ApiBoot:ApiBootSecret@localhost:8080/oauth/token -d "grant_type=password&username=api-boot&password=123456"
  2.  
  3. {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTMxMDk1MjMsInVzZXJfbmFtZSI6ImFwaS1ib290IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjBmZTUyY2RlLTBhZjctNDI1YS04Njc2LTFkYTUyZTA0YzUxYiIsImNsaWVudF9pZCI6IkFwaUJvb3QiLCJzY29wZSI6WyJhcGkiXX0.ImqGZssbDEOmpf2lQZjLQsch4ukE0C4SCYJsutfwfx0","token_type":"bearer","expires_in":42821,"scope":"api","jti":"0fe52cde-0af7-425a-8676-1da52e04c51b"}

启用JWT

ApiBoot Security Oauth在使用JWT格式化access_token时非常简单的,配置如下所示:

  1. api:
  2. boot:
  3. oauth:
  4. jwt:
  5. # 开启Jwt转换AccessToken
  6. enable: true
  7. # 转换Jwt时所需加密key,默认为ApiBoot
  8. sign-key: 恒宇少年 - 于起宇

默认不启用JWTsign-key签名建议进行更换。