OAuth2.0-3客户端授权放到数据库

Posted jiawen010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OAuth2.0-3客户端授权放到数据库相关的知识,希望对你有一定的参考价值。

授权得客户端信息、授权码信息全都存在数据库

技术图片

 

 

技术图片

 

 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申请令牌

技术图片

 

 已经存入了数据库

技术图片

 

 技术图片

 

 

验证令牌

技术图片

 

以上是关于OAuth2.0-3客户端授权放到数据库的主要内容,如果未能解决你的问题,请参考以下文章

InputStreamReader抛出NullPointerException [duplicate]

tp5邮箱POP3发送邮件验证码放到服务器上就不能用了为什么

使用 Git 来管理 Xcode 中的代码片段

HTTP客户端代码片段

微信小程序+php 授权登陆,完整代码

ThinkPHP中使用PHPMailer发送邮件