SpringBoot整合Oauth2开放平台接口授权案例


        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.projectlombok
            lombok
        

        
        
            org.springframework.boot
            spring-boot-starter-freemarker
        

        spring-boot 整合security -->
        
            org.springframework.boot
            spring-boot-starter-security
        
        
        
            org.springframework.cloud
            spring-cloud-starter-oauth2
        

二、授权中心案例代码

Oauth2相关配置:

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description: 配置授权中心信息
 * @date 2020-05-03 13:21
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    /**
     * accessToken有效期 两小时
     */
    private int accessTokenValiditySeconds = 7200;

    /**
     * refreshToken有效期 两小时
     */
    private int refreshTokenValiditySeconds = 7200;

    /**
     * 添加商户信息
     *
     * @param clients 商户
     * @throws Exception 异常
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //商户id
                .withClient("client_1")
                //商户secret
                .secret(passwordEncoder().encode("123456"))
                //回调地址
                .redirectUris("https://www.baidu.com/")
                /* OAuth2为我们提供了四种授权方式:
                 * 1、授权码模式(authorization code)用在客户端与服务端应用之间授权
                 * 2、简化模式(implicit)用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)
                 * 3、密码模式(resource owner password credentials)应用直接都是受信任的(都是由一家公司开发的)
                 * 4、客户端模式(client credentials)用在应用API访问
                 */
                .authorizedGrantTypes("password", "client_credentials", "refresh_token", "authorization_code")
                //授权范围
                .scopes("all")
                //accessToken有效期
                .accessTokenValiditySeconds(accessTokenValiditySeconds)
                //refreshToken有效期
                .refreshTokenValiditySeconds(refreshTokenValiditySeconds);
    }

    /**
     * 设置token类型
     * @param endpoints
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager())
                .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);
        endpoints.authenticationManager(authenticationManager());
        endpoints.userDetailsService(userDetailsService());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        // 允许表单认证
        oauthServer.allowFormAuthenticationForClients();
        // 允许check_token访问
        oauthServer.checkTokenAccess("permitAll()");
    }

    @Bean
    AuthenticationManager authenticationManager() {
        AuthenticationManager authenticationManager = new AuthenticationManager() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                return daoAuhthenticationProvider().authenticate(authentication);
            }

        };
        return authenticationManager;
    }

    @Bean
    public AuthenticationProvider daoAuhthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService());
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        return daoAuthenticationProvider;
    }

    /**
     * 设置添加用户信息,正常应该从数据库中读取
     *
     * @return UserDetailsService
     */
    @Bean
    UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
        userDetailsService.createUser(User.withUsername("user_1").password(passwordEncoder().encode("123456"))
                .authorities("ROLE_USER").build());
        userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("1234567"))
                .authorities("ROLE_USER").build());
        return userDetailsService;
    }

    /**
     * 设置加密方式
     *
     * @return PasswordEncoder
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Security相关配置:

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description: 添加Security权限配置
 * @date 2020-05-03 13:59
 */
@Component
public class SecurityConfig  extends WebSecurityConfigurerAdapter {

    /**
     *  授权中心管理器
     * @return AuthenticationManager
     * @throws Exception 异常
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     *  拦截所有请求,使用httpBasic方式登陆
     * @param http 请求
     * @throws Exception 异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
    }

}

测试授权码模式:

访问http://localhost:8080/oauth/authorize?response_type=code&client_id=client_1&redirect_uri=https://www.baidu.com/

SpringBoot整合Oauth2开放平台接口授权案例_第1张图片

SpringBoot整合Oauth2开放平台接口授权案例_第2张图片

使用该授权码获取accessToken:

访问http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=client_1&client_secret=123456&code=EwaTib&redirect_uri=https://www.baidu.com/&scope=all

SpringBoot整合Oauth2开放平台接口授权案例_第3张图片

测试密码模式获取accessToken:

SpringBoot整合Oauth2开放平台接口授权案例_第4张图片

三、受保护应用端案例代码

全局配置:

server:
  port: 8081

logging:
  level:
    org.springframework.security: DEBUG

security:
  oauth2:
    resource:
      ####从认证授权中心上验证token
      tokenInfoUri: http://localhost:8080/oauth/check_token
      preferTokenInfo: true
    client:
      accessTokenUri: http://localhost:8080/oauth/token
      userAuthorizationUri: http://localhost:8080/oauth/authorize
      ###appid
      clientId: client_1
      ###appSecret
      clientSecret: 123456

资源拦截配置:

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description: 资源拦截配置
 * @date 2020-05-03 15:43
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 对 api/order 请求进行拦截
        http.authorizeRequests().antMatchers("/api/test/**").authenticated();
    }

}

资源服务请求测试类:

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description:
 * @date 2020-05-03 15:44
 */
@RestController
@RequestMapping("/api/test")
public class TestController {

    @RequestMapping("/add")
    public String addOrder() {
        return "add success!";
    }

 启动类开启Oauth2

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description:
 * @date 2020-05-03 15:42
 */
@SpringBootApplication
@EnableOAuth2Sso
public class TestOauth2Server {
    public static void main(String[] args) {
        SpringApplication.run(TestOauth2Server.class,args);
    }
}

四、授权中心和受保护应用端联合测试

1)、没授权时:

2)、授权时:

先获取token

SpringBoot整合Oauth2开放平台接口授权案例_第5张图片

再用token访问资源

SpringBoot整合Oauth2开放平台接口授权案例_第6张图片

五、修改授权中心改成动态数据库查询的方式

下载官方数据库脚本:spring-security-oauth/schema.sql at main · spring-attic/spring-security-oauth · GitHub

SpringBoot整合Oauth2开放平台接口授权案例_第7张图片

新增数据库依赖:

       
        
            mysql
            mysql-connector-java
        

        
            org.springframework.boot
            spring-boot-starter-jdbc
        
spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1
      minimum-idle: 1
      maximum-pool-size: 5
      pool-name: dbcp1
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/zhq_test_oauth?autoReconnect=true&useSSL=false
    username: root
    password: root

 修改Oauth2配置:

/**
 * @author Mr.Zheng
 * @Program: parent
 * @Description: 配置授权中心信息
 * @date 2020-05-03 13:21
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {


    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;


    /**
     * accessToken有效期 两小时
     */
    private int accessTokenValiditySeconds = 7200;

    /**
     * refreshToken有效期 两小时
     */
    private int refreshTokenValiditySeconds = 7200;

    @Bean
    public TokenStore tokenStore() {
        // return new InMemoryTokenStore(); //使用内存中的 token store
        return new JdbcTokenStore(dataSource); /// 使用Jdbctoken store
    }


    /**
     * 添加商户信息
     *
     * @param clients 商户
     * @throws Exception 异常
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource)
                //测试首次运行可以指定测试数据,如果数据库中没有则不报错,如果有或者第二次运行会报错,因为数据库已经存在了,需要注释掉
                .withClient("client_1")
                //商户secret
                .secret(passwordEncoder().encode("123456"))
                //回调地址
                .redirectUris("https://www.baidu.com/")
                /* OAuth2为我们提供了四种授权方式:
                 * 1、授权码模式(authorization code)用在客户端与服务端应用之间授权
                 * 2、简化模式(implicit)用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)
                 * 3、密码模式(resource owner password credentials)应用直接都是受信任的(都是由一家公司开发的)
                 * 4、客户端模式(client credentials)用在应用API访问
                 */
                .authorizedGrantTypes("password", "client_credentials", "refresh_token", "authorization_code")
                //授权范围
                .scopes("all")
                //accessToken有效期
                .accessTokenValiditySeconds(accessTokenValiditySeconds)
                //refreshToken有效期
                .refreshTokenValiditySeconds(refreshTokenValiditySeconds);
    }

    /**
     * 设置token类型
     * @param endpoints
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager())
                .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);
        endpoints.authenticationManager(authenticationManager());
        endpoints.userDetailsService(userDetailsService());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        // 允许表单认证
        oauthServer.allowFormAuthenticationForClients();
        // 允许check_token访问
        oauthServer.checkTokenAccess("permitAll()");
    }

    @Bean
    AuthenticationManager authenticationManager() {
        AuthenticationManager authenticationManager = new AuthenticationManager() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                return daoAuhthenticationProvider().authenticate(authentication);
            }

        };
        return authenticationManager;
    }

    @Bean
    public AuthenticationProvider daoAuhthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService());
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        return daoAuthenticationProvider;
    }

    /**
     * 设置添加用户信息,正常应该从数据库中读取
     *
     * @return UserDetailsService
     */
    @Bean
    UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
        userDetailsService.createUser(User.withUsername("user_1").password(passwordEncoder().encode("123456"))
                .authorities("ROLE_USER").build());
        userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("1234567"))
                .authorities("ROLE_USER").build());
        return userDetailsService;
    }

    /**
     * 设置加密方式
     *
     * @return PasswordEncoder
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

测试运行:

SpringBoot整合Oauth2开放平台接口授权案例_第8张图片

检查数据库发现测试商户已经导入到数据库了

你可能感兴趣的:(spring,boot,spring,java)