精华内容
下载资源
问答
  • oauth2.0:oauth2.0-源码

    2021-06-09 18:25:44
    oauth2.0 Java 中的 OAuth2.0 实现。 它使用 apache-oltu 和 jersey 插件。 代码是用Java开发的
  • Oauth2.0 该项目是SpringSecurity对Oauth2.0的实现,包含三个服务:认证授权服务端、客户端、资源服务端(可选)
  • PWMIS.OAuth2.0 授权认证服务程序说明 主要目的 本示例演示了OAuth 2.0的具体使用过程,与网络上其它示例不同的是,本示例的系统各个角色是分开,即授权服务器和资源服务器是分开设计部署的 ASP.NET站点。同时,还有...
  • 包含 1.Getting Started with OAuth 2.0.pdf 2.Mastering OAuth 2.0.pdf 3.Oauth2 in Action.pdf 4.OAuth2.0 Cookbook.pdf
  • jfinal-oauth2.0-server jfinal-oauth2.0-server 基于,, 参考 实现了4.节描述的内容。 实现了OAuth 2.0定义了四种授权方式 授权码模式(authorization code): 先获取下次请求token的code,然后在带着code去请求...
  • 一、OAuth2.0 介绍 1.1 OAuth 认证标准 OAuth(开放授权) 是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容,...

    一、OAuth2.0 介绍

    1.1 OAuth 认证标准

    OAuth(开放授权) 是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容,OAuth2.0 是 OAuth 协议的延续版本。

     

    1.2 OAuth 和 OAuth2.0的区别

    引用:

    https://blog.csdn.net/u013436121/article/details/23631885

     

    1.3 OAuth2.0 认证流程

    OAuth2.0 的模块分为几部分:

    • 客户端:本身不存储资源,需要通过用户的授权去请求资源服务器的资源。客户端如:商城安卓端、商城web端等
    • 资源拥有者:通常为用户,即该资源信息的拥有者
    • 认证服务器:用例对资源拥有者的身份进行认证,对访问资源授权。客户端想要访问资源,必须使用资源拥有者给予的授权码来认证服务器获取令牌
    • 资源服务器:存储资源的服务器,如用户信息等。客户端最终使用令牌从资源服务器获取信息

            

    例如:使用微信登录商城

    1.4 OAuth2.0 授权模式

    • 授权码模式(Authorization Code) => 常用
    • 密码模式(Resource Owner Password Credentials) => 常用
    • 隐式授权模式(Implicit) => 不常用
    • 客户端模式(Client Credentials) => 不常用

     

    1.5 授权码模式流程

    • 客户端请求第三方授权
    • 用户同意给客户端授权
    • 客户端获取到授权码,请求认证服务器申请令牌
    • 认证服务器向客户端响应令牌
    • 客户端请求资源服务器的资源,资源服务校验令牌合法性,完成授权
    • 资源服务器返回受保护资源

     

    二、SSO 实现(SpringSecurity + Oauth2.0)

    使用 Spring security + Oauth2.0 实现用户认证和用户授权。 Spring security 是一个强大的和高度可定制的身份验证和访问控制框架,其继承了 Oauth2.0 协议。

    2.1 流程模型图

      

      

     

     

    2.2 非对称加密算法实现本地令牌验证

    由于传统的授权模式性能低下,每次都需要请求授权服务器校验令牌合法性,则会造成多于的请求,且拖慢响应速度。故使用非对称算法,利用公钥私钥完成对令牌的加密。

    若加密成功,则表示令牌合法。若校验失败,则令牌无效不合法。

    旧框架:

      

    新框架: 本地令牌验证

      

     

    2.2.1 RSA 非对称算法介绍

    特点:公钥和私钥是成对的,它们互相解密

    加解密: 公钥加密,私钥解密

    签名:私钥签名,公钥验签

    转载:RSA公钥,私钥和数字签名简单理解

     

    2.2.2 生成公私钥

    生成秘钥证书

    秘钥证书中包含公钥和私钥

    创建一个文件夹,并执行如下命令

    keytool -genkeypair -alias tom -keyalg RSA -keypass tomtom -keystore tom.jks -storepass tomtom

    Keytool 是一个 java 的证书管理工具

    -alias:密钥的别名
    -keyalg:使用的 hash 算法
    -keypass:密钥的访问密码,能够读出证书
    -keystore:密钥库文名
    -storepass:密钥库的访问密码,能够解密数据

      

    相关操作命令

    # 查看证书信息
    keytool -list -keystore tom.jks
    
    # 删除别名
    keytool -delete -alias tom -keystore tom.jks

     

    2.2.3 导出公钥

    可以使用 openssl 来导出公钥信息

    下载地址:

    http://slproweb.com/products/Win32OpenSSL.html

    网盘下载:

    链接:https://pan.baidu.com/s/1Ov3gUtpGPHKFSc9iqC-sug     提取码:ir26

    配置环境变量:

    OPENSSL_CONF
    D:\Common\OpenSSL-Win64\bin\openssl.cfg

      

    在 Path 中增加:

    D:\Common\OpenSSL-Win64\bin

      

    导出公钥

    keytool -list -rfc --keystore tomtom.jks | openssl x509 -inform pem -pubkey

      

    保存公钥到文件中,公钥必须整理成同一行

      

    修改配置文件:

    2.2.4 测试

    import com.alibaba.fastjson.JSON;
    import org.junit.Test;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.security.jwt.Jwt;
    import org.springframework.security.jwt.JwtHelper;
    import org.springframework.security.jwt.crypto.sign.RsaSigner;
    import org.springframework.security.jwt.crypto.sign.RsaVerifier;
    import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
    
    import java.security.KeyPair;
    import java.security.PrivateKey;
    import java.security.interfaces.RSAPrivateKey;
    import java.util.HashMap;
    import java.util.Map;
    
    public class CreateJWTTestDemo {
    
        @Test
        public void testCreateToken() {
            // 加载证书
            ClassPathResource resource = new ClassPathResource("tomtom.jks");
            // 读取证书数据
            KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource, "tomtom".toCharArray());
    
            //  获取证书中的一对秘钥
            KeyPair keyPair = keyStoreKeyFactory.getKeyPair("tomtom", "tomtom".toCharArray());
    
            // 获取私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    
            // 创建令牌,使用私钥加盐[RSA]
            Map<String, Object> payload = new HashMap<String, Object>();
            payload.put("nickname", "tomcat");
            payload.put("address", "xiamen");
            payload.put("role", "admin, user");
    
            Jwt jwt = JwtHelper.encode(JSON.toJSONString(payload), new RsaSigner(privateKey));
    
            // 获取令牌数据
            String token = jwt.getEncoded();
    
            System.out.println(token);
        }
    
        @Test
        public void testParseToken() {
            String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZGRyZXNzIjoieGlhbWVuIiwicm9sZSI6ImFkbWluLCB1c2VyIiwibmlja25hbWUiOiJ0b21jYXQifQ.A0QrW0_Kk66G4fMdbFKPwJdsWmkwXJ4-8pymoJe28KGfuWtjOJKLZxdzjPuw9wItjoxTNHMWDCrLOxLCVuKbShIxpJDsmWecrmSjR6a8ZqBXqtw3-V_C-AYqJlyxHy7rfzCZzZDQ8GvyY7u4cFcx-iv42g9yVOLDc2DpnzvQ9uoLNYrqQuhagmEUtqrgHMX5OBYM1OP11VEjURVRt2tCOHX2Q285rkN-bgFgXtyscBkjjf5IGbiDXi6sofLTi_Ei2lEftvbhLNAi1LEQitCaZlqkh_ZsQ4d2RtJmP_vkRKCBHRhe0PNChIg0KI5TJ8fDeHgMfsEahcKbNfDdujfRzA";
            String publicKey = "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmI1RoiNIK6nP+GrlCTPSSR1ResUCDLHQ5o6kyA9wyqYj/8S8Xgjyp9AKf8e0AB+Yid0mjtVHQyt3PSXPPSAvypeKvGWyVaCuLEmUtE1FX2VcvPqdmEiGBhtF1cwGh+9DAGxp0tNUjbsVaS3A3QxR5MLWTbMJZFGlD2xhKjGc8qju/3UHKgbH1SDZKBJRk+Wdv7AWO5nf9sH2KDBo4Vm2HMwhfoPrrslIEBNfcaRqD317n5szvtDGd6zMSYA9ENOQ8dx1Yf2bve/B2jTQVdtO+v3uhKn2AAOChvVmjpdvVxXFWDmEBy+nUpMswMjheizlo0AWs8BqXdns9geY1E6icQIDAQAB-----END PUBLIC KEY-----";
            Jwt jwt = JwtHelper.decodeAndVerify(token,
                    new RsaVerifier(publicKey));
            String claims = jwt.getClaims();
            System.out.println(claims);
        }
    }
    

     

    2.3 流程分析

        

    流程分析:

    • 用户登录,请求认证服务
    • 认证服务认证通过,生成 jwt 令牌,并写入 cookie 中
    • 用户访问资源时,带着 cookie 到网关
    • 网关从 cookie 中获取 token,如果存在 token,则验证其合法性,若不合法则拒绝访问,合法则放行
    • 用户退出时,请求认证服务,删除 cookie 中的 token

     

     

     

     

     

     

     

     

     

    展开全文
  • OAuth 2.0客户端的Basecamp提供程序 该软件包为PHP League的提供了Basecamp OAuth 2.0支持。 安装 要安装,请使用作曲家: composer require uberboom/oauth2-basecamp 用法 用法与The League的OAuth客户端相同,...
  • ReactGoogle OAuth 2.0 轻松将Google OAuth 2.0单一登录添加到React应用,并让您的服务器处理您的访问和刷新令牌。 该库可直接与配合使用,并以最少的设置立即提供Google OAuth 2.0集成。 文件: : 安装 npm ...
  • OAuth2.0-PHP 用于OAuth2.0实现PHP库-Beta 1.0 当前的示例项目带有包含的库,无需任何特殊设置即可工作。 您可以使用随附的oAuth_2_0.json通过Postman测试创建的端点。 PHP版本> = 5.3 安装: 下载/克隆项目 将...
  • 学习OAuth 2.0最系统的介绍,从入门到掌握授权、认证的原理,开发必备。
  • oauth2.0

    2020-12-28 08:48:55
    OAuth2.0 OAuth2.0是OAuth协议的延续版本,但不向前兼容OAuth 1.0(即完全废止了OAuth1.0)。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,要么允许第...

    OAuth2.0

    OAuth2.0是OAuth协议的延续版本,但不向前兼容OAuth 1.0(即完全废止了OAuth1.0)。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限。同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012年10月,OAuth 2.0协议正式发布为RFC 6749 [1]  。

    中文名

    开放授权

    外文名

    OAuth2.0

    定    义

    协议的下一版本

    简易性

    OAuth1.0。 OAuth 2.0

    应用领域

    计算机网路、认证

    娱    乐

    视频

    目录

     

    1. 前言
    2. 认证授权过程
    3. ▪ 简单历史回顾
    4. ▪ 6种全新流程

    前言

     

    OAuth 1.0已经在IETF(国际互联网工程任务组),编号是RFC5849

    这也标志着OAuth已经正式成为互联网标准协议。

    OAuth 2.0早已经开始讨论和建立的草案。OAuth2.0很可能是下一代的“用户验证和授权”标准。现在百度开放平台腾讯开放平台等大部分的开放平台都是使用的OAuth 2.0协议作为支撑。

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

    OAuth

    允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

    OAuth是OpenID的一个补充,但是完全不同的服务。

    OAuth 2.0

    是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012年10月,OAuth 2.0协议正式发布为RFC 6749 [1]  。

    Facebook的新的Graph API只支持OAuth 2.0,Google在2011年3月亦宣布Google API对OAuth 2.0的支持。

    认证授权过程

     

    在认证和授权的过程中涉及的三方包括:

    1、服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。

    2、用户,存放在服务提供方的受保护的资源的拥有者。

    3、客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。

    使用OAuth进行认证和授权的过程如下所示:

    用户想操作存放在服务提供方的资源。

    用户登录客户端向服务提供方请求一个临时令牌。

    服务提供方验证客户端的身份后,授予一个临时令牌。

    客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方。

    用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。

    授权成功后,服务提供方引导用户返回客户端的网页。

    客户端根据临时令牌从服务提供方那里获取访问令牌。

    服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。

    客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。

    简单历史回顾

     

    OAuth 1.0在2007年的12月底发布并迅速成为工业标准。

    2008年6月,发布了OAuth 1.0 Revision A,这是个稍作修改的修订版本,主要修正一个安全方面的漏洞。

    2010年四月,OAuth 1.0的终于在IETF发布了,协议编号RFC 5849。

    OAuth 2.0的草案是在2011年5月初在IETF发布的。

    OAuth is a security protocol that enables users to grant third-party access to their web resources without sharing their passwords.

    OAuth是个安全相关的协议,作用在于,使用户授权第三方的应用程序访问用户的web资源,并且不需要向第三方应用程序透露自己的密码。

    OAuth 2.0是个全新的协议,并且不对之前的版本做向后兼容,然而,OAuth 2.0保留了与之前版本OAuth相同的整体架构。

    这个草案是围绕着 OAuth2.0的需求和目标,历经了长达一年的讨论,讨论的参与者来自业界的各个知名公司,包括Yahoo!, Facebook, Salesforce, Microsoft, Twitter, Deutsche Telekom, Intuit, Mozilla, and Google。

    OAuth 2.0的新特性:

    6种全新流程

     

    User-Agent Flow – 客户端运行于用户代理内(典型如web浏览器)。

    Web Server Flow – 客户端是web服务器程序的一部分,通过http request接入,这是OAuth 1.0提供的流程的简化版本。

    Device Flow – 适用于客户端在受限设备上执行操作,但是终端用户单独接入另一台电脑或者设备的浏览器

    Username and Password Flow – 这个流程的应用场景是,用户信任客户端处理身份凭据,但是仍然不希望客户端储存他们的用户名和密码,这个流程仅在用户高度信任客户端时才适用。

    Client Credentials Flow – 客户端适用它的身份凭据去获取access token,这个流程支持2-legged OAuth的场景。

    Assertion Flow – 客户端用assertion去换取access token,比如SAML assertion。

    可以通过使用以上的多种流程实现Native应用程序对OAuth的支持(程序运行于桌面操作系统或移动设备)

    application support (applications running on a desktop or mobile device) can be implemented using many of the flows above.

    持信人token

    OAuth 2.0 提供一种无需加密的认证方式,此方式是基于现存的cookie验证架构,token本身将自己作为secret,通过HTTPS发送,从而替换了通过 HMAC和token secret加密并发送的方式,这将允许使用cURL发起APIcall和其他简单的脚本工具而不需遵循原先的request方式并进行签名。

    签名简化:

    对于签名的支持,签名机制大大简化,不需要特殊的解析处理,编码,和对参数进行排序。使用一个secret替代原先的两个secret。

    短期token和长效的身份凭据

    原先的OAuth,会发行一个 有效期非常长的token(典型的是一年有效期或者无有效期限制),在OAuth 2.0中,server将发行一个短有效期的access token和长生命期的refresh token。这将允许客户端无需用户再次操作而获取一个新的access token,并且也限制了access token的有效期。

    角色分开

    OAuth 2.0将分为两个角色:

    Authorization server负责获取用户的授权并且发布token。

    Resource负责处理API calls。

    展开全文
  • OAuth 2.0

    2020-04-14 22:21:47
  • jfinal-oauth2.0-server 基于, 参考实现了4.节描述的内容。 实现了OAuth 2.0定义了四种授权方式 授权码模式(authorization code): 先获取下次请求token的code,然后在带着code去请求token; 简化模式(implicit...
  • Spring Security 的 OAuth 2.0 Client 特性为 OAuth 2.0 鉴权框架 中定义的 Client 角色提供了支持 高层的核心特性有: Authorization Grant 支持 在 OAuth 2.0 中,Authorization Grant 表示授权码类型 授权码是一...

    样例代码:Spring Security Sample

    参考:Spring Security Reference


    Spring Security 的 OAuth 2.0 Client 特性为 OAuth 2.0 鉴权框架 中定义的
    Client 角色提供了支持

    高层的核心特性有:

    Authorization Grant 支持

    在 OAuth 2.0 中,Authorization Grant 表示授权码类型
    授权码是一个用来换取 Access Token 的 code,它代表着资源所有者对三方系统的授权
    OAuth 2.0 支持多种类型的授权码,并且还支持扩展自定义的授权码类型
    其中一种扩展,就是集成 Assertion 框架
    将其中的 Assertion 作为授权码
    而 Assertion 的具体实现又需要其它的框架支持,例如 SAMLJWT

    另外,OAuth 2.0 还包括 Client 鉴权,即授权服务器认证三方系统身份的流程(可选的)
    这个流程也支持 JWT 扩展

    Client 鉴权支持

    HTTP 客户端支持

    Servlet 环境的 WebClient 集成,就是一个 HTTP 客户端,用来发送 HTTP 请求
    集成后,可以在 Client 后端发起访问资源服务的 HTTP 请求时使用

    HttpSecurity.oauth2Client() DSL 概览:

    @Component
    public class Oauth2Config extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .oauth2Client(oauth2ClientConfigurer -> oauth2ClientConfigurer
                    .clientRegistrationRepository(clientRegistrationRepository())
                    .authorizedClientRepository(authorizedClientRepository())
                    .authorizedClientService(authorizedClientService())
                    .authorizationCodeGrant(codeGrant -> codeGrant
                        .authorizationRequestRepository(authorizationRequestRepository())
                        .authorizationRequestResolver(authorizationRequestResolver())
                        .accessTokenResponseClient(accessTokenResponseClient())
                    )
                );
        }
    
    }
    

    1. 核心接口 / 类

    ClientRegistration

    ClientRegistration 代表一个注册到 OAuth 2.0 或 OpenID Connect 1.0 提供者(Provider)的 Client

    一个 ClientRegistration 中保存了关于 Client 的信息:

    package org.springframework.security.oauth2.client.registration;
    
    public final class ClientRegistration {
        
        private String registrationId; // ClientRegistration 的唯一标识
        private String clientId; // OAuth2 标准中的 Client ID,向授权服务器标识 Client 的身份
        private String clientSecret; // OAuth2 标准中的 Client Secret
      
        /*
        请求供应商(Provider)认证 Client 身份时使用的方法,支持的方法有:
        client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt, none
         */
        private ClientAuthenticationMethod clientAuthenticationMethod;
        
        /*
        OAuth 2.0 授权框架定义的授权码类型,支持的类型有:
        authorization_code, client_credentials, password, as well as, urn:ietf:params:oauth:grant-type:jwt-bearer(扩展的类型)
         */
        private AuthorizationGrantType authorizationGrantType;
        
        /*
        Client 注册到授权中心的重定向 URI
        当终端用户鉴权成功,并为 Client 授权访问之后,授权中心会让用户代理(如:浏览器)重定向到这个 URI
         */
        private String redirectUri;
        
        private Set<String> scopes = Collections.emptySet(); // Client 请求的 scope(权限)如:openid, email, or profile
        private ProviderDetails providerDetails = new ProviderDetails();
        private String clientName; // Client 的一个描述性的名称,例如在登录页上展示三方登录的名称
    
        public class ProviderDetails {
            
            private String authorizationUri; // 授权服务器的授权接口 URI(Authorization Endpoint)
            private String tokenUri; // 授权服务器用于通过授权码换取 Access Token 的接口(Token Endpoint)
            private UserInfoEndpoint userInfoEndpoint = new UserInfoEndpoint();
            
            /*
            从授权服务器查询 JSON Web Key (JWK) Set 的接口
            JWK 中包含用于验证 ID Token(OpenID Connect 会用到) 的 JSON Web Signature (JWS) 的密钥  
            也可以用于验证 UserInfo 响应(从资源服务器获取的用户信息)
             */
            private String jwkSetUri;
    
            // 返回 OpenID Connect 1.0 提供者(Provider)或 OAuth 2.0 授权服务器的发行者标识
            private String issuerUri;
    
            /*
            OpenID Provider Configuration Information
            这个信息只有在 Spring Boot 2.x 配置了 spring.security.oauth2.client.provider.[providerId].issuerUri 属性时可用
             */
            private Map<String, Object> configurationMetadata = Collections.emptyMap();
    
            public class UserInfoEndpoint {
    
                // 向资源服务器查询终端用户信息的 URI(UserInfo Endpoint)
                private String uri;
                
                // 用 Access Token 访问 UserInfo Endpoint 获取用户信息时使用的的方法
                private AuthenticationMethod authenticationMethod = AuthenticationMethod.HEADER;
                
                // 访问 UserInfo Endpoint 后返回的用户信息响应(UserInfo Response)中,用户名的参数名称(用户名泛指唯一标识终端用户的信息)
                private String userNameAttributeName;   
    
            }
            
        }
    
    }
    

    参考:JSON Web Key (JWK)JSON Web Signature (JWS)OpenID Provider Configuration Information

    一个 ClientRegistration 可以通过下边两种发现机制进行配置

    1. OpenID Connect 提供者(Provider)的 Configuration endpoint
    2. 授权服务器的 Metadata endpoint

    ClientRegistrations 提供了通过这种发现机制来配置 ClientRegistration 的方法:

    @Component
    public class Oauth2Config extends WebSecurityConfigurerAdapter {
    
        ClientRegistration clientRegistration() {
            return ClientRegistrations.fromIssuerLocation("https://idp.example.com/issuer").build();
        }
      
    }
    

    上边的代码会依次访问下边的 URL 直到获得 200 状态码:

    1. https://idp.example.com/issuer/.well-known/openid-configuration
    2. https://idp.example.com/.well-known/openid-configuration/issuer
    3. https://idp.example.com/.well-known/oauth-authorization-server/issuer

    使用第一个 200 状态码的响应来配置 ClientRegistration

    也可以使用 ClientRegistrations.fromOidcIssuerLocation(String issuer)
    这个方法只会访问 OpenID Connect 提供者(Provider)的 Configuration endpoint

    ClientRegistrationRepository

    ClientRegistrationRepository 作为存储 OAuth 2.0 / OpenID Connect 1.0 的 ClientRegistration 的仓库

    Client 注册信息由相关的授权服务器所有,最终也是以存储在授权服务器的信息为准
    ClientRegistrationRepository 存储的是完整 Client 注册信息的一个子集,并且需要与授权服务器存储的注册信息保持一致
    ClientRegistrationRepository 是否通过授权服务器提供的接口同步 Client 注册信息,以及如何同步取决于具体实现

    ClientRegistrationRepository 的默认实现是 InMemoryClientRegistrationRepository
    用一个 Map<String, ClientRegistration> 存储 registrationId -> ClientRegistration 映射

    Spring Boot 2.x 的自动配置会将 spring.security.oauth2.client.registration.[registrationId] 下的属性绑定到 ClientRegistration 实例
    然后将这些 ClientRegistration 存入 ClientRegistrationRepository

    自动配置还会将 ClientRegistrationRepository 注册为 ApplicationContext 中的 @Bean,在应用中,可以通过依赖注入获取

    @RestController
    @RequestMapping("test")
    public class TestController {
    
        @Autowired
        private ClientRegistrationRepository clientRegistrationRepository;
    
        @GetMapping("foo/registration")
        public String fooRegistration() {
        ClientRegistration fooRegistration = clientRegistrationRepository.findByRegistrationId("foo");
            return fooRegistration == null ? "fooRegistration == null" : fooRegistration.toString();
        }
    
    }
    

    OAuth2AuthorizedClient

    OAuth2AuthorizedClient 代表一个已被授权的 Client
    当终端用户(资源拥有者)向某个 Client 授予了访问受保护资源的权限时,这个 Client 被认为是已被授权的 Client

    OAuth2AuthorizedClientOAuth2AccessToken(可选的 OAuth2RefreshToken)和 ClientRegistration 与资源拥有者关联起来
    其中的 Principal 指的是终端用户(资源拥有者)

    OAuth2AuthorizedClientRepository / OAuth2AuthorizedClientService

    OAuth2AuthorizedClientRepository 负责在 Web 请求之间持久化 OAuth2AuthorizedClient(通常对应会话域)

    从开发者的角度来看,OAuth2AuthorizedClientRepository 或者 OAuth2AuthorizedClientService 提供了查找某个 Client 对应的 OAuth2AccessToken 的方法
    在向资源服务器发起访问用户资源的请求时,必须要先获取 OAuth2AccessToken

    @RestController
    @RequestMapping("test")
    public class TestController {
    
        @Autowired
        private OAuth2AuthorizedClientService oauth2AuthorizedClientService;
    
        // ...
      
        @GetMapping("foo/accesstoken")
        public String fooAccessToken(Authentication authentication) {
            OAuth2AuthorizedClient authorizedClient = oauth2AuthorizedClientService
               .loadAuthorizedClient("foo", authentication.getName());
            return authorizedClient.getAccessToken().getTokenType().getValue();
        }
    
    }
    

    Spring Boot 2.x 的自动配置在 ApplicationContext 注册了 OAuth2AuthorizedClientRepository 和/或 OAuth2AuthorizedClientService @Bean
    客户端程序员也可以注册自己的 OAuth2AuthorizedClientRepositoryOAuth2AuthorizedClientService @Bean

    OAuth2AuthorizedClientService 的默认实现是 InMemoryOAuth2AuthorizedClientService
    在内存中存储 OAuth2AuthorizedClient

    可以配置 JdbcOAuth2AuthorizedClientService 通过 JDBC 将 OAuth2AuthorizedClient 持久化到数据库

    JdbcOAuth2AuthorizedClientService 依赖 OAuth 2.0 Client Schema 中的数据库表结构

    OAuth2AuthorizedClientManager / OAuth2AuthorizedClientProvider

    OAuth2AuthorizedClientManager 负责对 OAuth2AuthorizedClient 进行管理

    其主要责任有:

    1. 使用 OAuth2AuthorizedClientProvider 为 OAuth 2.0 Client 授权(或重新授权)
    2. 委托 OAuth2AuthorizedClientServiceOAuth2AuthorizedClientRepositoryOAuth2AuthorizedClient 进行持久化
    3. 当一个 OAuth 2.0 Client 被成功授权(或重新授权)后,委托 OAuth2AuthorizationSuccessHandler 进行处理
    4. 当一个 OAuth 2.0 Client 授权(或重新授权)失败后,委托 OAuth2AuthorizationFailureHandler 进行处理

    OAuth2AuthorizedClientProvider 会实现一个为 OAuth 2.0 Client 授权(或重新授权)的策略
    一般会实现一种授权码类型(Authorization Grant),例如:authorization_code、client_credentials 等

    OAuth2AuthorizedClientManager 的默认实现是 DefaultOAuth2AuthorizedClientManager
    这个实现关联着一个基于委派组合的支持多种授权码类型的 OAuth2AuthorizedClientProvider
    这个实现是用 OAuth2AuthorizedClientProviderBuilder 构建的 DelegatingOAuth2AuthorizedClientProvider 对象
    客户端程序员也可以使用 OAuth2AuthorizedClientProviderBuilder 配置并构建一个基于委派组合的 DelegatingOAuth2AuthorizedClientProvider

    下边的例子展示了如何用 OAuth2AuthorizedClientProviderBuilder 配置并构建一个 DelegatingOAuth2AuthorizedClientProvider
    支持:authorization_code、refresh_token、client_credentials、基于密码的授权

    @Component
    public class Oauth2Config extends WebSecurityConfigurerAdapter {
    
        @Bean
        public OAuth2AuthorizedClientManager authorizedClientManager(
            ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientRepository authorizedClientRepository) {
    
            OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
                .authorizationCode()
                .refreshToken()
                .clientCredentials()
                .password()
                .build();
    
            DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
                clientRegistrationRepository, authorizedClientRepository);
            authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    
            return authorizedClientManager;
        }
    
    }
    

    授权成功后,DefaultOAuth2AuthorizedClientManager 会调用 OAuth2AuthorizationSuccessHandler.onAuthorizationSuccess()
    OAuth2AuthorizationSuccessHandler 默认会通过 OAuth2AuthorizedClientRepository 保存 OAuth2AuthorizedClient

    重新授权失败后,例如 Refresh Token 失效了
    RemoveAuthorizedClientOAuth2AuthorizationFailureHandler 会将之前保存的 OAuth2AuthorizedClientOAuth2AuthorizedClientRepository 中移除
    可以通过 setAuthorizationSuccessHandler(OAuth2AuthorizationSuccessHandler)setAuthorizationFailureHandler(OAuth2AuthorizationFailureHandler) 配置自定义处理器

    DefaultOAuth2AuthorizedClientManager 持有一个 contextAttributesMapper,类型为 Function<OAuth2AuthorizeRequest, Map<String, Object>>
    负责将 OAuth2AuthorizeRequest 中的属性放入一个属性值的 Map,这个 Map 的值会被加入到 OAuth2AuthorizationContext
    某些 OAuth2AuthorizedClientProvider 需要用到请求中的参数,这时就可以通过这种方式获取到
    例如 PasswordOAuth2AuthorizedClientProvider 需要从 OAuth2AuthorizationContext.getAttributes() 中获取资源拥有者的用户名和密码

    contextAttributesMapper 这个函数式提供了一个接入点,可以自定义从请求获取需要属性的具体方式:

    @Component
    public class Oauth2Config extends WebSecurityConfigurerAdapter {
    
        @Bean
        OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientRepository authorizedClientRepository) {
    
            OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
                .password()
                .refreshToken()
                .build();
    
            DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
                clientRegistrationRepository, authorizedClientRepository);
            authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    
            /*
            假设 `用户名` 和 `密码` 由 `HttpServletRequest` 参数提供
            将 `HttpServletRequest` 参数映射到 `OAuth2AuthorizationContext.getAttributes()`
             */
            authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
    
            return authorizedClientManager;
        }
    
        private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributesMapper() {
            return oauth2AuthorizeRequest -> {
                Map<String, Object> contextAttributes = Collections.emptyMap();
                HttpServletRequest servletRequest = oauth2AuthorizeRequest.getAttribute(HttpServletRequest.class.getName());
                String username = null, password = null;
                if (servletRequest != null) {
                    username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
                    password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
                }
                if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
                    contextAttributes = new HashMap<>();
                    // `PasswordOAuth2AuthorizedClientProvider` 需要这两个属性
                    contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
                    contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
                }
                return contextAttributes;
              };
        }
        
    }
    

    DefaultOAuth2AuthorizedClientManager 被设计为在 HttpServletRequest 上下文中使用
    如果操作不在 HttpServletRequest 上下文中,则应该使用 AuthorizedClientServiceOAuth2AuthorizedClientManager

    服务应用(Service Application)是一个常见的使用 AuthorizedClientServiceOAuth2AuthorizedClientManager 的场景
    服务应用通常在后端运行,不与用户交互,通常使用系统级别的账户而不是普通用户账户
    此时可以使用 client_credentials 类型的授权码

    下边是一个通过配置 AuthorizedClientServiceOAuth2AuthorizedClientManager 支持 client_credentials 类型授权码的例子:

    @Component
    public class A04_ClientCredentialOauth2ClientConfig extends WebSecurityConfigurerAdapter {
        
        @Bean
        OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientService authorizedClientService) {
    
            AuthorizedClientServiceOAuth2AuthorizedClientManager
                authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(
                    clientRegistrationRepository, authorizedClientService);
            
            OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
                .clientCredentials()
                .build();
            authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    
            return authorizedClientManager;
        }
    
    }
    

    2. “ 授权码类型 ” 支持

    3. “ Client 授权 ” 支持

    4. 其它特性

    5. Servlet 环境集成 WebClient


    样例代码:Spring Security Sample

    展开全文
  • OAuth 2.0 (一)——对 OAuth 2.0 的理解 1. 是什么 OAuth 2.0 OAuth 是一个关于认证、授权的标准。而 Spring Security OAuth 是 Spring Boot 对 OAuth 的实现。目前 OAuth 的最高版本是 2.0版。 2. 为什么使用 ...
  • OAuth2.0

    2016-10-03 00:44:34
    因为博客迁移,有些图片显示不出,原文章地址:... OAuth2.0原理: OAuth2.0流程: OAuth2.0授权方式: 授权码模式  简化模式  密码模式  客户端模式  ...
  • oauth2.0授权码 OAuth 2.0提供了许多安全流程(或授权类型),以允许一个应用程序访问另一个应用程序中的用户数据。 在此博客中,我们将介绍OAuth 2.0授权:授权代码授权。 首先,有许多定义: 客户端 :...
  • 深入理解基于OAuth2.0&amp;amp;第三方登录之GitHub实践基于OAuth2.0的第三方登录第三方登录的实质几个重要概念为什么需要加入第三方登录OAuth2.0协议规范流程最典型的Authorization Code 授权模式为何引入...
  • 基于wechat公众平台,sae,webpy实现Oauth2.0 测试用例:手机微信扫描‘公众号的二维码’,关注该公众号,单击下方菜单栏‘用户授权’选项,授权完成后,会出现显示个人信息的页面。########### 编写思路:实现授权...
  • 为什么会有OAuth 2.0 OAuth 2.0是什么 OAuth 2.0 可以用来做什么 OAuth 2.0 有几种方式可以实现 作为OAuth 2.0的提供方, 需要提供哪些内容 作为OAuth 2.0的接入方, 需要做哪些事情 以App开发举例, 我们一般会有两种...
  • oAuth 2.0

    2020-11-08 23:05:00
    OAuth 2.0 OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。 简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的...
  • OAuth2.0授权模式 OAuth2.0支持如下四种授权模式,其中安全级别最高的是授权码模式。我们先了解一下在代码中如何简单的实现四种授权模式,下一篇在介绍关于四种授权模式的选型。 授权码 密码式 隐藏式 客户端...
  • 在《OAuth2.0协议入门(一):OAuth2.0协议的基本概念以及使用授权码模式(authorization code)实现百度账号登录》中,介绍了OAuth2.0协议的基本概念以及作为一个第三方应用在请求授权服务端的时候需要做哪些事情。...
  • oauth2.0协议流程 什么是OAuth 2.0 OAuth 2.0是一个已被广泛采用的委托授权框架,已经存在了很多年,并且似乎已经存在。 如果您不熟悉OAuth 2.0的基本概念,可以使用 川崎孝彦写的优秀文章 。 这只是OAuth 2.0各方...
  • Oauth2.0本身: Oauth2.0是一种授权协议,当然也归属为安全协议的范畴,在实际执行的时候就是保护互联网中不断增长的大量WEB API的安全访问。OAuth2.0共包含四种角色,分别是资源所有者、第三方应用(也称为客户端...
  • 如果你是用oauth2.0,就会存在一个问题。oauth2.0自身支持四种授权模式,分别是: authorization code(授权码模式) implicit(简化模式) resource owner password credentials(密码模式) client crede
  • 全面认识第三方授权机制 oauth2.0 协议,如何在 php 上搭建 oauth2.0服务端!对应博文如下:https://blog.csdn.net/xh870189248/article/details/85126364

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,745
精华内容 13,898
关键字:

oauth2.0