授权码模式-云接云-oauth2-米家-小爱音箱-智能家居

oauth2接入米家开发者

工具

  • idea
  • 花生壳(自己电脑web服务可以使用公网访问)
  • 浏览器
  • 米家企业开发者账号

代码

  • 目录结构

    • 在这里插入图片描述
  • pom

    • <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.6.1</version>
              <relativePath/> <!-- lookup parent from repository -->
          </parent>
          <groupId>com.example</groupId>
          <artifactId>demo6</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <name>demo6</name>
          <description>demo6</description>
          <properties>
              <java.version>1.8</java.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>
                  <version>2.3.4.RELEASE</version>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.springframework.security</groupId>
                  <artifactId>spring-security-test</artifactId>
                  <scope>test</scope>
              </dependency>
          </dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                      <configuration>
                          <excludes>
                              <exclude>
                                  <groupId>org.projectlombok</groupId>
                                  <artifactId>lombok</artifactId>
                              </exclude>
                          </excludes>
                      </configuration>
                  </plugin>
              </plugins>
          </build>
      
      </project>
      
  • AuthServerConfiguration(资源认证服务器)

    • package com.example.config;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.http.HttpMethod;
      import org.springframework.security.crypto.password.PasswordEncoder;
      import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
      import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
      import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
      import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
      import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
      @Configuration
      @EnableAuthorizationServer
      public class AuthServerConfiguration  extends AuthorizationServerConfigurerAdapter {
          /**
           * 密码加密器
           */
          @Autowired
          private PasswordEncoder passwordEncoder;
      
          /**
           * 认证服务默认是post请求,允许可以通过get请求认证
           * @param endpoints
           * @throws Exception
           */
          @Override
          public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
              endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);
          }
      
          /**
           * 认证服务默认是basic认证,允许可以通过表单请求认证
           * @param security
           * @throws Exception
           */
          @Override
          public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
              security.allowFormAuthenticationForClients();
          }
          @Override
          public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
              // 配置米家 测试账号
              clients.inMemory()
                      .withClient("test")
                      .secret(passwordEncoder.encode("123456"))
                      .redirectUris("http://other")
                      .authorizedGrantTypes("authorization_code","password","refresh_token","implicit","client_credentials")
                      .scopes("all")
                      .autoApprove(true)
                     ;
          }
      }
      
  • ResourceServerConfiguration(资源保护过滤器)

    • package com.example.config;
      
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
      import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
      import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
      
      @Configuration
      @EnableResourceServer
      public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
          @Override
          public void configure(HttpSecurity http) throws Exception {
              http
                      /**
                       * 只拦截oauth2 请求需要认证服务验证
                       * 类似于 http://localhost:8080/oauth2/xxx?access_token=code
                       */
                      .antMatcher("/oauth2/**")
                      .authorizeRequests()
                      // 其他请求 交给下一个拦截器
                      .anyRequest().authenticated();
          }
      }
      
  • WebSecurityConfiguration(web请求拦截器)

    • package com.example.config;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
      import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
      import org.springframework.security.core.userdetails.User;
      import org.springframework.security.core.userdetails.UserDetailsService;
      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
      import org.springframework.security.crypto.password.PasswordEncoder;
      import org.springframework.security.provisioning.InMemoryUserDetailsManager;
      @EnableWebSecurity
      @Configuration
      public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
          /**
           * 密码加密 必须
           * @return
           */
          @Bean
          public PasswordEncoder passwordEncoder(){
              return new BCryptPasswordEncoder();
          }
      
          /**
           * 使用内存用户管理器创建两个用户 并且赋有两个角色
           * @return
           */
          @Override
          protected UserDetailsService userDetailsService() {
              InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
              inMemoryUserDetailsManager.createUser(User.withUsername("admin").password(passwordEncoder().encode("123")).roles("admin").build());
              inMemoryUserDetailsManager.createUser(User.withUsername("user").password(passwordEncoder().encode("123")).roles("user").build());
              return inMemoryUserDetailsManager;
          }
      
          /**
           * 这个功能可以让输入的账号不需要转换加密
           * @param auth
           * @throws Exception
           */
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
          }
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http
                      .authorizeRequests()
                      // 处理user开头的需要user角色
                      .antMatchers("/user/**").hasRole("user")
                      .antMatchers("/admin/**").hasRole("admin")
                      // 以下请求放行
                      .antMatchers("/oauth/**","/login/**","/logout/**").permitAll()
                      // 其他请求 放到别的过滤器中
                      .anyRequest()
                      .authenticated()
                      .and()
                      // 使用表单验证账户
                      .formLogin()
                      .permitAll()
                      .and()
                      .csrf().disable();
          }
      
      }
      

测试

  • 这里没有写接口请求返回,所以能返回404就是访问成功,别的就表明没有访问成功

  • http://localhost:8080/oauth2/test

    • 会被资源保护器拦截
    • 在这里插入图片描述
  • http://localhost:8080/user/test

    • 会跳转到登录页面然后输入admin+123

    • 在这里插入图片描述

    • 会出现403没有角色

    • 在这里插入图片描述

    • 将网址改为/admin/test表示可以正常访问角色正确

    • 在这里插入图片描述

  • http://localhost:8080/oauth/authorize?response_type=code&client_id=test&scope=all&redirect_uri=http://other

    • 如果要访问/oauth2/**接口,先要获取请求令牌,跳出登录页面,随便登上一个账号admin+123会返回一个码gJNW6u

    • 在这里插入图片描述

    • http://localhost:8080/oauth/token?grant_type=code&client_id=test&client_secret=123456&code=gJNW6u&redirect_uri=http://other (会得出我们所需要的access_token)

    • 在这里插入图片描述

    • http://localhost:8080/oauth2/test?access_token=cd70264c-5c0f-4f39-9996-573021b83311 (我们能上面得到access_token cd70264c-5c0f-4f39-9996-573021b83311,然后再重新请求保护资源)

    • 在这里插入图片描述

米家接入测试

  • 启动花生壳,将服务映射出去,网上找教程,最终效果如下

  • 在这里插入图片描述

  • 然后打开米家开发平台,需要企业开发账号才可以选项

  • 在这里插入图片描述

  • 然后编辑配置,需要跟上面资源验证服务器代码,完全一致,这里要注意跳转地址,是米家开发给出的,要将代码中redirectUris()里面http://other改成https://oauth-redirect.api.home.mi.com/r/xxxxx,然后重启服务

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 然后重启idea服务.再返回米家,点击测试,输入账号密码点击login然后返回表示成功

  • 在这里插入图片描述

总结
oauth/** 会被资源认证服务器拦截
oauth2/** 会被资源保护服务器拦截
别的请求 会被web请求服务器拦截

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值