SpringSecurityOAuth2多个第三方登录配置

SpringSecurityOAuth2多个第三方登录配置

继上一篇对使用第三方登录有了初体验后,这篇继续学习,这篇要做的很简单,就是配置多个第三方登录,上一篇用来Github,这次咱们加上Gitee看看是不是操作完全都一样。

使用OAuth2的授权码模式

1. 环境搭建

环境搭建部分与上一篇保持一致,复制下模块,更改下名字。
然后主要更改是在配置文件

2. 开始动手

  1. 增加多一个Gitee的授权登录

关于gitee中创建应用的就不多啰嗦了,可以自己在设置中找找,或者直接百度

按照之前的做法,咱们先在application.yaml中配置gitee,可能会这样子配置:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            clientId: xxxx # 填入自己应用的clientId
            clientSecret: xxxxx # 填入自己应用的clientSecret
            redirectUri: http://localhost:8844/login/oauth2/code/github
          gitee:
            clientId: xxxx # 填入自己应用的clientId
            clientSecret: xxxxx # 填入自己应用的clientSecret
            redirectUri: http://localhost:8844/login/oauth2/code/gitee
  1. 直接启动运行程序
    这时会发现启动失败,报错了:
    在这里插入图片描述

大概理解意思就是提供商gitee的id并没有指定,一脸懵,为啥GitHub的就完全没问题,gitee就不行呢?

这是因为SpringSecurity默认配置好了GitHub的Provider信息,而Gitee的没有,因此找不到Gitee的,我们可以看看官网的说明

在这里插入图片描述

这里说的很清楚了:SpringSecurity的OAuth2有一个CommonOAuth2Provider预定义了几个比较知名的提供商:Google,Github,Facebook,Okta,因此对于这几个提供商,可以只配置clientIdclientSecret.

咱们可以看看这个CommonOAuth2Provider源码:

public enum CommonOAuth2Provider {
    GOOGLE {
        public Builder getBuilder(String registrationId) {
            Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
            builder.scope(new String[]{"openid", "profile", "email"});
            builder.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
            builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
            builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
            builder.issuerUri("https://accounts.google.com");
            builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
            builder.userNameAttributeName("sub");
            builder.clientName("Google");
            return builder;
        }
    },
    GITHUB {
        public Builder getBuilder(String registrationId) {
            Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
            builder.scope(new String[]{"read:user"});
            builder.authorizationUri("https://github.com/login/oauth/authorize");
            builder.tokenUri("https://github.com/login/oauth/access_token");
            builder.userInfoUri("https://api.github.com/user");
            builder.userNameAttributeName("id");
            builder.clientName("GitHub");
            return builder;
        }
    },
    FACEBOOK {
        public Builder getBuilder(String registrationId) {
            Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.CLIENT_SECRET_POST, "{baseUrl}/{action}/oauth2/code/{registrationId}");
            builder.scope(new String[]{"public_profile", "email"});
            builder.authorizationUri("https://www.facebook.com/v2.8/dialog/oauth");
            builder.tokenUri("https://graph.facebook.com/v2.8/oauth/access_token");
            builder.userInfoUri("https://graph.facebook.com/me?fields=id,name,email");
            builder.userNameAttributeName("id");
            builder.clientName("Facebook");
            return builder;
        }
    },
    OKTA {
        public Builder getBuilder(String registrationId) {
            Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
            builder.scope(new String[]{"openid", "profile", "email"});
            builder.userNameAttributeName("sub");
            builder.clientName("Okta");
            return builder;
        }
    };

    private static final String DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}";

    private CommonOAuth2Provider() {
    }

    protected final Builder getBuilder(String registrationId, ClientAuthenticationMethod method, String redirectUri) {
        Builder builder = ClientRegistration.withRegistrationId(registrationId);
        builder.clientAuthenticationMethod(method);
        builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
        builder.redirectUri(redirectUri);
        return builder;
    }

    public abstract Builder getBuilder(String registrationId);
}

可以看到这就是一个枚举,里面定义好了提供商需要提供的一些信息,比如scope,authorizationUri,tokenUri,userInfoUri,userNameAttributeName,clientName
关于这些属性的作用可以这样理解:

  • scope: 类似于权限
  • authorizationUri:认证的url
  • tokenUri: 获取access_token的url
  • userInfoUri: 获取用户信息的url
  • userNameAttributeName: 用户信息中用户名的属性名称
  • clientName: 客户端名称

接着继续看官网,肯定有教我们如何自定义的:
在这里插入图片描述

  1. 完善配置
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            clientId: xxxx # 填入自己应用的clientId
            clientSecret: xxxxx # 填入自己应用的clientSecret
            redirectUri: http://localhost:8844/login/oauth2/code/github
          gitee:
            clientId: xxxx # 填入自己应用的clientId
            clientSecret: xxxxx # 填入自己应用的clientSecret
            redirectUri: http://localhost:8844/login/oauth2/code/gitee
            authorizationGrantType: authorization_code
        provider:
          gitee:
            authorizationUri: https://gitee.com/oauth/authorize
            tokenUri: https://gitee.com/oauth/token
            userInfoUri: https://gitee.com/api/v5/user
            userNameAttribute: name

注意这里配置Gitee时还需要提供authorizationGrantType,我们用的是授权码模式,因此写上authorization_code

  1. 运行测试
  • 访问本地http://localhost:8844/hello, 会展示多个登录选择,这里是github和gitee
    在这里插入图片描述

  • 点击gitee,会跳转到gitee的登录页面,之后都跟之前一样了,就不啰嗦了。

3. 扩展

前面我们访问的路径都是/hello,只是返回一个"Hello World"的字符串,主打一个简单粗暴。
但是一般我们第三方登录其实要的就是用户信息,那我们怎么拿到这个信息?talk is cheap,show me the code

@GetMapping("/user")
public Map<String, Object> hello(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Map<String, Object> map = new HashMap<>(2);
    map.put("oauth2client", oAuth2AuthorizedClient);
    map.put("authentication", authentication);

    return map;
}

通过加上注解@RegisteredOAuth2AuthorizedClient就可以拿到已经授权登录成功的用户信息了

4. 总结

通过这一篇文章,我了解到了原来配置其他的第三方登录,是需要自己提供Provider的,还有如何获取到已经授权登录的用户信息。
下一篇就来学习下源码,走下源码流程,看看具体是个怎么回事。

最后为把代码都上传到Github了,如果觉得有用,帮帮忙点个Start。
我的Github

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值