场景:甲方爸爸,是知名机械类厂子,外国的。然后他们普遍是对接微软的。希望的效果是,除去系统本身的账号密码登录。我用我电脑上的微软账号也能登录你们的系统。

处理的方法:妥妥的第三方登录,不多说,开冲!

微软第三方登录:

1.微软开放平台申请

  1. 前往 https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade 注册应用
  2. 在注册应用的时候就需要填写回调地址,当然后期也可以重新修改

    国内如何登录dockerhub 国内如何登录disney_java

  3. client id 在这里

    国内如何登录dockerhub 国内如何登录disney_第三方登录_02

  4. client secret 需要自己在这里生成

    国内如何登录dockerhub 国内如何登录disney_第三方登录_03

代码实践处理:

2. 主要代码

代码地址:https://github.com/xkcoding/spring-boot-demo/tree/master/spring-boot-demo-social
本 demo 采用 Redis 缓存 state,所以请准备 Redis 环境,如果没有 Redis 环境,可以将配置文件的缓存配置为

复制

> justauth: > cache: > type: default >

2.1. pom.xml

复制

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <artifactId>spring-boot-demo-social</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-boot-demo-social</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>com.xkcoding</groupId>
    <artifactId>spring-boot-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <justauth-spring-boot.version>1.1.0</justauth-spring-boot.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- 对象池,使用redis时必须引入 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>

    <!-- oauth工具类 -->
    <dependency>
      <groupId>com.xkcoding</groupId>
      <artifactId>justauth-spring-boot-starter</artifactId>
      <version>${justauth-spring-boot.version}</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </dependency>

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
    </dependency>
  </dependencies>

  <build>
    <finalName>spring-boot-demo-social</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

2.2. application.yml

复制

server:
  port: 8080
  servlet:
    context-path: /demo

spring:
  redis:
    host: localhost
    # 连接超时时间(记得添加单位,Duration)
    timeout: 10000ms
    # Redis默认情况下有16个分片,这里配置具体使用的分片
    # database: 0
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制) 默认 8
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
        max-wait: -1ms
        # 连接池中的最大空闲连接 默认 8
        max-idle: 8
        # 连接池中的最小空闲连接 默认 0
        min-idle: 0
  cache:
    # 一般来说是不用配置的,Spring Cache 会根据依赖的包自行装配
    type: redis

justauth:
  enabled: true
  type:
    qq:
      client-id: 10******85
      client-secret: 1f7d************************d629e
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/qq/callback
    github:
      client-id: 2d25******d5f01086
      client-secret: 5a2919b************************d7871306d1
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/github/callback
    wechat:
      client-id: wxdcb******4ff4
      client-secret: b4e9dc************************a08ed6d
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat/callback
    google:
      client-id: 716******17-6db******vh******ttj320i******userco******t.com
      client-secret: 9IBorn************7-E
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/google/callback
    microsoft:
      client-id: 7bdce8******************e194ad76c1b
      client-secret: Iu0zZ4************************tl9PWan_.
      redirect-uri: https://oauth.xkcoding.com/demo/oauth/microsoft/callback
    mi:
      client-id: 288************2994
      client-secret: nFeTt89************************==
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/mi/callback
    wechat_enterprise:
      client-id: ww58******f3************fbc
      client-secret: 8G6PCr00j************************rgk************AyzaPc78
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_enterprise/callback
      agent-id: 1*******2
  cache:
    type: redis
    prefix: 'SOCIAL::STATE::'
    timeout: 1h

2.3. OauthController.java

复制

/**
 * <p>
 * 第三方登录 Controller
 * </p>
 *
 * @package: com.xkcoding.oauth.controller
 * @description: 第三方登录 Controller
 * @author: yangkai.shen
 * @date: Created in 2019-05-17 10:07
 * @copyright: Copyright (c) 2019
 * @version: V1.0
 * @modified: yangkai.shen
 */
@Slf4j
@RestController
@RequestMapping("/oauth")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class OauthController {
    private final AuthRequestFactory factory;

    /**
     * 登录类型
     */
    @GetMapping
    public Map<String, String> loginType() {
        List<String> oauthList = factory.oauthList();
        return oauthList.stream().collect(Collectors.toMap(oauth -> oauth.toLowerCase() + "登录", oauth -> "http://oauth.xkcoding.com/demo/oauth/login/" + oauth.toLowerCase()));
    }

    /**
     * 登录
     *
     * @param oauthType 第三方登录类型
     * @param response  response
     * @throws IOException
     */
    @RequestMapping("/login/{oauthType}")
    public void renderAuth(@PathVariable String oauthType, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        response.sendRedirect(authRequest.authorize(oauthType + "::" + AuthStateUtils.createState()));
    }

    /**
     * 登录成功后的回调
     *
     * @param oauthType 第三方登录类型
     * @param callback  携带返回的信息
     * @return 登录成功后的信息
     */
    @RequestMapping("/{oauthType}/callback")
    public AuthResponse login(@PathVariable String oauthType, AuthCallback callback) {
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        AuthResponse response = authRequest.login(callback);
        log.info("【response】= {}", JSONUtil.toJsonStr(response));
        return response;
    }

    private AuthSource getAuthSource(String type) {
        if (StrUtil.isNotBlank(type)) {
            return AuthSource.valueOf(type.toUpperCase());
        } else {
            throw new RuntimeException("不支持的类型");
        }
    }
}

2.4. 如果想要自定义 state 缓存()

3.个人demo实现

首先是微软的回调地址 仅限https: 或者http://localhost

所以内网穿透 需要对应穿透网址加上https 或者采用证书(证书没太大意义,不是很推荐,项目上线一定是https接口的)

个人修改地方

国内如何登录dockerhub 国内如何登录disney_spring_04

对应处理

国内如何登录dockerhub 国内如何登录disney_redis_05

修改成 内网穿透之后的

页面展示

https://fuhua.mynatapp.cc/demo/oauth/

国内如何登录dockerhub 国内如何登录disney_redis_06

对应微软登录的 网址为 https://fuhua.mynatapp.cc/demo/oauth/login/microsoft

这步骤是demo需要运行的 充当当前页面展示

国内如何登录dockerhub 国内如何登录disney_spring_07

国内如何登录dockerhub 国内如何登录disney_java_08

1对应是否成功 成功为2000

2是对应登录账号

3是对应登录成功之后的 token返回

控制台打印

2020-07-31 11:58:56.000 INFO 16012 — [nio-8443-exec-3] c.x.social.controller.OauthController : 【response】= {“code”:2000,“data”:{“gender”:“UNKNOWN”,“nickname”:"",“source”:“MICROSOFT”,“uuid”:“33cbede99d184e40”,“username”:“942560375@qq.com”,“token”:{“scope”:“User.Read Mail.Read”,“expireIn”:3600,“accessToken”:“EwBQA8l6BAAUO9chh8cJscQLmU+LSWpbnr0vmwwAAadV42aYCTmOpaxyd1/6HEP9GTZsgy7ddUBi5AjtgtiXIVbLh52Idxufvb7mFA2sX2V6eLgxurVHlpyUHxRRIes2O2L4Eei7EQMhf6z0/rddF+yauGu+0clsM1YROA3ZcSrQLWg8V0lPNrpdoB1ChYIz1WOJrpfHIktzylwrXzlRacSRqPiIjJqDXnazVveRzMoB4YxucLr2mqo13zpE0vIWQD9S4ySz9+2gwOb2AkT270EPz2um0vy2B0gbf+M3q5T0tZZew1nY/gDfyYtUzmW4Y88QraPARp+3INvPCUhqX7id/u/BHdtbZo8AQWlXYU7rX87HWqm45OJtIwlfflcDZgAACJc80wiCH7ENIAL5N97mcpnnstZdMMMiJKd0TiEiQWLTBX5pE0UvDs/YJajLyz4/kyn3MFImLzjZO7IrgG4HEKB/Ip3htBEMEFrdtsJzqbfbzDyrPP04PFQbOn/lITQQk1CHhXBYQoxaBQ28GjhvUjBrJE/1M8x6GdyKoNXcSxc5hZFcB53VqmYYS8rZAJRqhEAbztwSRtII1zWdg4oMBCBwv9HteD8X8AivGFz7MOdcMbpkUlWDetZW0tkdlKwZslBMjsYP5+PuSsBgXy1Iq0lZUzvNvN4TNXzeGPXUVUXgyzf5k1u6Ibhw1+ML35lL0YiSkuh7QWOXhDdseW7tEcmyaxNBYeP3xuhqyKOqrW/JQRt6zri6tLaIG0fHXxzyRxMOsnPDEPWbQMHcPNQP48SQJ2b8A4lOEizak8YqtAKHM6vwXjlzR+/M5/Sswel4A8Vp1MMmg59tcIgU6FGxXkWDLM+n3iUe7PktcGf6Z6brePq/mbCAdoT0EvYEtEMrt7d8AijG/lTvnz0YIP28YVqVdCiALHLBNrvH7zmhzm8EXXWIyCoVE24rhKUsoSCyt25TiVMx4XQdzg3+SGynEvlub7/EtEp0kU0oqVVnVm2tNHolOiFy2SswoqT1uGP4oxR+S9dEuKG8Ah7hG7a566cDRswUhrsObEjHQvB3k/m07A1gZACobZggJRwciUQZOrDwV03PbX06QzY2wuHc1XaEmX6vOKaHs9rNYgI=”,“tokenType”:“Bearer”,“refreshToken”:“MCaDsWTG8NzYU8kjqVsTCZQ3pc99UppnekwtIkborJzENTBKoTyUawq2T6JQtqObpzCx2!2nwO0c1kKsnrNP2SvIQSaYVvJ9RkKqKl!97xh8ROUwUcbDQS2MPmNCY2D14qC5N9KShcaIXWHH8GjbRnx2I07fewhSfM30hLZ2AFPvYYQBlubRKSigtGhhPVuyEMGGRgqSnZpdOTswM4s!369d1UwaG8zONnSoCm9qukLMwPkIQ0Le1uUpTHYzrp5uV89uiD2TwuAYPpUrZrEXlyaQOLc78mCHcxTqwdE4eppmoleg8XnXjGPEgRKAMeGi0q8v!haRaTO3k2mKY**nizhWBPWmk5ysnmN9x2ERqBNf5aQ2oyJWuWma*6YDG5uiNAbZDJWfEc3qJJ7rmZQYuUC!wwa0xbGWTL0Jj8kNY”}}}

这是demo中控制台输出结果

4.跟现在项目的逻辑对接

国内如何登录dockerhub 国内如何登录disney_java_09

最后这部分当时做的时候有笔记所以给上传到百度云下载。主要是怕图片挂掉,不过目前似乎越来越好了。别说了,我还是截图上传了图片。应该是我自己没有放图床问题导致

链接:https://pan.baidu.com/s/1fTkePXngBYwqdfYyQKKISA
提取码:fw6j

对应内容可以分享,互联网就是互相帮助。指不定你帮助的小伙伴就是你下一个身边的伙伴。助人=帮助自己。


漫漫长路,一个小周跟他一个小陈朋友一起努力奔跑。