552.5191109c.js 29.2 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1
(window.webpackJsonp=window.webpackJsonp||[]).push([[552],{980:function(t,e,i){"use strict";i.r(e);var n=i(56),r=Object(n.a)({},(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[i("h1",{attrs:{id:"核心配置"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#核心配置"}},[t._v("#")]),t._v(" 核心配置")]),t._v(" "),i("h2",{attrs:{id:"spring-启动-2-x-示例"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#spring-启动-2-x-示例"}},[t._v("#")]),t._v(" Spring 启动 2.x 示例")]),t._v(" "),i("p",[t._v("Spring Boot2.x 为 OAuth2.0 登录带来了完整的自动配置功能。")]),t._v(" "),i("p",[t._v("本节展示如何使用"),i("em",[t._v("谷歌")]),t._v("作为"),i("em",[t._v("身份验证提供者")]),t._v("配置"),i("a",{attrs:{href:"https://github.com/spring-projects/spring-security-samples/tree/5.6.x/reactive/webflux/java/oauth2/login",target:"_blank",rel:"noopener noreferrer"}},[t._v("**OAuth2.0 登录 WebFlux 样本 **"),i("OutboundLink")],1),t._v(",并涵盖以下主题:")]),t._v(" "),i("ul",[i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-sample-setup"}},[t._v("初始设置")])])]),t._v(" "),i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-sample-redirect"}},[t._v("设置重定向 URI")])])]),t._v(" "),i("li",[i("p",[t._v("[configure"),i("code",[t._v("application.yml")]),t._v("](#WebFlux-OAuth2-login-sample-config)")])]),t._v(" "),i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-sample-start"}},[t._v("启动应用程序")])])])]),t._v(" "),i("h3",{attrs:{id:"初始设置"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#初始设置"}},[t._v("#")]),t._v(" 初始设置")]),t._v(" "),i("p",[t._v("要使用 Google 的 OAuth2.0 身份验证系统进行登录,你必须在 Google API 控制台中设置一个项目,以获得 OAuth2.0 凭据。")]),t._v(" "),i("table",[i("thead",[i("tr",[i("th"),t._v(" "),i("th",[t._v("用于身份验证的"),i("a",{attrs:{href:"https://developers.google.com/identity/protocols/OpenIDConnect",target:"_blank",rel:"noopener noreferrer"}},[t._v("谷歌的 OAuth2.0 实现"),i("OutboundLink")],1),t._v("符合"),i("a",{attrs:{href:"https://openid.net/connect/",target:"_blank",rel:"noopener noreferrer"}},[t._v("OpenID Connect1.0"),i("OutboundLink")],1),t._v("规范,并且是"),i("a",{attrs:{href:"https://openid.net/certification/",target:"_blank",rel:"noopener noreferrer"}},[t._v("OpenID 认证"),i("OutboundLink")],1),t._v("")])])]),t._v(" "),i("tbody")]),t._v(" "),i("p",[t._v("按照"),i("a",{attrs:{href:"https://developers.google.com/identity/protocols/OpenIDConnect",target:"_blank",rel:"noopener noreferrer"}},[t._v("OpenID 连接"),i("OutboundLink")],1),t._v("页面上的说明,从“设置 OAuth2.0”一节开始。")]),t._v(" "),i("p",[t._v("在完成“获取 OAuth2.0 凭据”说明之后,你应该有一个新的 OAuth 客户机,其凭据由一个客户机 ID 和一个客户机秘密组成。")]),t._v(" "),i("h3",{attrs:{id:"设置重定向-uri"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#设置重定向-uri"}},[t._v("#")]),t._v(" 设置重定向 URI")]),t._v(" "),i("p",[t._v("重定向 URI 是应用程序中的路径,终端用户的用户代理在与 Google 进行身份验证并授予对同意页面上的 OAuth 客户端 "),i("em",[t._v(""),i("a",{attrs:{href:"#webflux-oauth2-login-sample-setup"}},[t._v("在前一步中创建")]),t._v("")]),t._v(" 的访问权限后,会被重定向回应用程序中的路径。")]),t._v(" "),i("p",[t._v("在“设置重定向 URI”子节中,确保将"),i("strong",[t._v("授权重定向 URI")]),t._v("字段设置为"),i("code",[t._v("[http://localhost:8080/login/oauth2/code/google](http://localhost:8080/login/oauth2/code/google)")]),t._v("")]),t._v(" "),i("table",[i("thead",[i("tr",[i("th"),t._v(" "),i("th",[t._v("默认的重定向 URI 模板是"),i("code",[t._v("{baseUrl}/login/oauth2/code/{registrationId}")]),t._v(""),i("br"),t._v("***注册 ID***是"),i("RouterLink",{attrs:{to:"/client/core.html#oauth2Client-client-registration"}},[t._v("客户登记")]),t._v("的唯一标识符。"),i("br"),t._v("对于我们的示例,"),i("code",[t._v("registrationId")]),t._v(""),i("code",[t._v("google")]),t._v("")],1)])]),t._v(" "),i("tbody")]),t._v(" "),i("table",[i("thead",[i("tr",[i("th"),t._v(" "),i("th",[t._v("如果 OAuth 客户端运行在代理服务器后面,建议检查"),i("RouterLink",{attrs:{to:"/features/exploits/http.html#http-proxy-server"}},[t._v("代理服务器配置")]),t._v("以确保应用程序配置正确。"),i("br"),t._v("此外,请参阅支持的["),i("code",[t._v("URI")]),t._v("模板变量](../client/Authorization-grants.html#OAuth2client-auth-code-redirect-uri)。")],1)])]),t._v(" "),i("tbody")]),t._v(" "),i("h3",{attrs:{id:"配置application-yml"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#配置application-yml"}},[t._v("#")]),t._v(" 配置"),i("code",[t._v("application.yml")])]),t._v(" "),i("p",[t._v("现在,你有了一个新的 OAuth 客户机和 Google,你需要将应用程序配置为使用"),i("em",[t._v("认证流程")]),t._v("的 OAuth 客户机。这样做:")]),t._v(" "),i("ol",[i("li",[i("p",[t._v("转到"),i("code",[t._v("application.yml")]),t._v("并设置以下配置:")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("spring:\n  security:\n    oauth2:\n      client:\n        registration:\t(1)\n          google:\t(2)\n            client-id: google-client-id\n            client-secret: google-client-secret\n")])])]),i("p",[t._v("例 1。OAuth 客户属性")]),t._v(" "),i("table",[i("thead",[i("tr",[i("th",[i("strong",[t._v("1")])]),t._v(" "),i("th",[i("code",[t._v("spring.security.oauth2.client.registration")]),t._v("是 OAuth 客户机属性的基本属性前缀。")])])]),t._v(" "),i("tbody",[i("tr",[i("td",[i("strong",[t._v("2")])]),t._v(" "),i("td",[t._v("在基本属性前缀之后是["),i("code",[t._v("ClientRegistration")]),t._v("](../client/core.html#OAuth2client-client-registration)的 ID,例如 Google。")])])])])]),t._v(" "),i("li",[i("p",[t._v("用前面创建的 OAuth2.0 凭据替换"),i("code",[t._v("client-id")]),t._v(""),i("code",[t._v("client-secret")]),t._v("属性中的值。")])])]),t._v(" "),i("h3",{attrs:{id:"启动应用程序"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#启动应用程序"}},[t._v("#")]),t._v(" 启动应用程序")]),t._v(" "),i("p",[t._v("启动 Spring boot2.x 示例,然后转到"),i("code",[t._v("[http://localhost:8080](http://localhost:8080)")]),t._v("。然后,你将被重定向到默认的"),i("em",[t._v("自动生成")]),t._v("登录页面,该页面显示了 Google 的链接。")]),t._v(" "),i("p",[t._v("点击谷歌链接,然后你将被重定向到谷歌进行身份验证。")]),t._v(" "),i("p",[t._v("在使用谷歌帐户凭据进行身份验证后,显示给你的下一页是“同意”屏幕。同意屏幕要求你允许或拒绝访问你之前创建的 OAuth 客户端。单击"),i("strong",[t._v("允许")]),t._v("授权 OAuth 客户端访问你的电子邮件地址和基本配置文件信息。")]),t._v(" "),i("p",[t._v("此时,OAuth 客户机从"),i("a",{attrs:{href:"https://openid.net/specs/openid-connect-core-1_0.html#UserInfo",target:"_blank",rel:"noopener noreferrer"}},[t._v("用户信息端点"),i("OutboundLink")],1),t._v("检索你的电子邮件地址和基本配置文件信息,并建立经过身份验证的会话。")]),t._v(" "),i("h2",{attrs:{id:"spring-启动-2-x-属性映射"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#spring-启动-2-x-属性映射"}},[t._v("#")]),t._v(" Spring 启动 2.x 属性映射")]),t._v(" "),i("p",[t._v("下表概述了 Spring Boot2.x OAuth 客户机属性到"),i("RouterLink",{attrs:{to:"/client/core.html#oauth2Client-client-registration"}},[t._v("客户登记")]),t._v("属性的映射。")],1),t._v(" "),i("table",[i("thead",[i("tr",[i("th",[t._v("Spring 启动 2.x")]),t._v(" "),i("th",[t._v("ClientRegistration")])])]),t._v(" "),i("tbody",[i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*")])]),t._v(" "),i("td",[i("code",[t._v("registrationId")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.client-id")])]),t._v(" "),i("td",[i("code",[t._v("clientId")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.client-secret")])]),t._v(" "),i("td",[i("code",[t._v("clientSecret")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.client-authentication-method")])]),t._v(" "),i("td",[i("code",[t._v("clientAuthenticationMethod")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.authorization-grant-type")])]),t._v(" "),i("td",[i("code",[t._v("authorizationGrantType")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.redirect-uri")])]),t._v(" "),i("td",[i("code",[t._v("redirectUri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.scope")])]),t._v(" "),i("td",[i("code",[t._v("scopes")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.registration.*[registrationId]*.client-name")])]),t._v(" "),i("td",[i("code",[t._v("clientName")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.authorization-uri")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.authorizationUri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.token-uri")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.tokenUri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.jwk-set-uri")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.jwkSetUri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.issuer-uri")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.issuerUri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.user-info-uri")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.userInfoEndpoint.uri")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.user-info-authentication-method")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.userInfoEndpoint.authenticationMethod")])])]),t._v(" "),i("tr",[i("td",[i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.user-name-attribute")])]),t._v(" "),i("td",[i("code",[t._v("providerDetails.userInfoEndpoint.userNameAttributeName")])])])])]),t._v(" "),i("table",[i("thead",[i("tr",[i("th"),t._v(" "),i("th",[t._v("通过指定"),i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*.issuer-uri")]),t._v("属性,可以使用发现 OpenID Connect 提供者的"),i("a",{attrs:{href:"https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig",target:"_blank",rel:"noopener noreferrer"}},[t._v("配置端点"),i("OutboundLink")],1),t._v("或授权服务器的"),i("a",{attrs:{href:"https://tools.ietf.org/html/rfc8414#section-3",target:"_blank",rel:"noopener noreferrer"}},[t._v("元数据端点"),i("OutboundLink")],1),t._v("来初始配置"),i("code",[t._v("ClientRegistration")]),t._v("")])])]),t._v(" "),i("tbody")]),t._v(" "),i("h2",{attrs:{id:"commonoauth2provider"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#commonoauth2provider"}},[t._v("#")]),t._v(" CommonoAuth2Provider")]),t._v(" "),i("p",[i("code",[t._v("CommonOAuth2Provider")]),t._v("为许多著名的提供商预先定义了一组默认的客户端属性:Google、GitHub、Facebook 和 OKTA。")]),t._v(" "),i("p",[t._v("例如,对于提供者,"),i("code",[t._v("authorization-uri")]),t._v(""),i("code",[t._v("token-uri")]),t._v(""),i("code",[t._v("user-info-uri")]),t._v("不会经常更改。因此,为了减少所需的配置,提供默认值是有意义的。")]),t._v(" "),i("p",[t._v("如前所述,当我们"),i("a",{attrs:{href:"#webflux-oauth2-login-sample-config"}},[t._v("配置了一个 Google 客户端")]),t._v("时,只需要"),i("code",[t._v("client-id")]),t._v(""),i("code",[t._v("client-secret")]),t._v("属性。")]),t._v(" "),i("p",[t._v("下面的清单展示了一个示例:")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("spring:\n  security:\n    oauth2:\n      client:\n        registration:\n          google:\n            client-id: google-client-id\n            client-secret: google-client-secret\n")])])]),i("table",[i("thead",[i("tr",[i("th"),t._v(" "),i("th",[t._v("客户机属性的自动默认在这里无缝地工作,因为"),i("code",[t._v("registrationId")]),t._v(""),i("code",[t._v("google")]),t._v(")匹配"),i("code",[t._v("GOOGLE``enum")]),t._v("(不区分大小写)中的"),i("code",[t._v("CommonOAuth2Provider")]),t._v("")])])]),t._v(" "),i("tbody")]),t._v(" "),i("p",[t._v("对于可能希望指定不同的"),i("code",[t._v("registrationId")]),t._v("的情况,例如"),i("code",[t._v("google-login")]),t._v(",你仍然可以通过配置"),i("code",[t._v("provider")]),t._v("属性来利用客户机属性的自动违约。")]),t._v(" "),i("p",[t._v("下面的清单展示了一个示例:")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("spring:\n  security:\n    oauth2:\n      client:\n        registration:\n          google-login:\t(1)\n            provider: google\t(2)\n            client-id: google-client-id\n            client-secret: google-client-secret\n")])])]),i("table",[i("thead",[i("tr",[i("th",[i("strong",[t._v("1")])]),t._v(" "),i("th",[t._v(""),i("code",[t._v("registrationId")]),t._v("设置为"),i("code",[t._v("google-login")]),t._v("")])])]),t._v(" "),i("tbody",[i("tr",[i("td",[i("strong",[t._v("2")])]),t._v(" "),i("td",[t._v(""),i("code",[t._v("provider")]),t._v("属性设置为"),i("code",[t._v("google")]),t._v(",这将利用"),i("code",[t._v("CommonOAuth2Provider.GOOGLE.getBuilder()")]),t._v("中设置的客户机属性的自动违约。")])])])]),t._v(" "),i("h2",{attrs:{id:"配置自定义提供程序属性"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#配置自定义提供程序属性"}},[t._v("#")]),t._v(" 配置自定义提供程序属性")]),t._v(" "),i("p",[t._v("有一些 OAuth2.0 提供程序支持多租赁,这会导致每个租户(或子域)的协议端点不同。")]),t._v(" "),i("p",[t._v("例如,向 OKTA 注册的 OAuth 客户端被分配到特定的子域并具有自己的协议端点。")]),t._v(" "),i("p",[t._v("对于这些情况, Spring Boot2.x 为配置自定义提供程序属性提供了以下基本属性:"),i("code",[t._v("spring.security.oauth2.client.provider.*[providerId]*")]),t._v("")]),t._v(" "),i("p",[t._v("下面的清单展示了一个示例:")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("spring:\n  security:\n    oauth2:\n      client:\n        registration:\n          okta:\n            client-id: okta-client-id\n            client-secret: okta-client-secret\n        provider:\n          okta:\t(1)\n            authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize\n            token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token\n            user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo\n            user-name-attribute: sub\n            jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys\n")])])]),i("table",[i("thead",[i("tr",[i("th",[i("strong",[t._v("1")])]),t._v(" "),i("th",[t._v("基本属性("),i("code",[t._v("spring.security.oauth2.client.provider.okta")]),t._v(")允许自定义配置协议端点位置。")])])]),t._v(" "),i("tbody")]),t._v(" "),i("h2",{attrs:{id:"覆盖-spring-启动-2-x-自动配置"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#覆盖-spring-启动-2-x-自动配置"}},[t._v("#")]),t._v(" 覆盖 Spring 启动 2.x 自动配置")]),t._v(" "),i("p",[t._v("OAuth 客户端支持的 Spring Boot2.x 自动配置类是"),i("code",[t._v("ReactiveOAuth2ClientAutoConfiguration")]),t._v("")]),t._v(" "),i("p",[t._v("它执行以下任务:")]),t._v(" "),i("ul",[i("li",[i("p",[t._v("从配置的 OAuth 客户机属性中寄存器"),i("code",[t._v("ReactiveClientRegistrationRepository``@Bean")]),t._v("组成的"),i("code",[t._v("ClientRegistration")]),t._v("")])]),t._v(" "),i("li",[i("p",[t._v("注册"),i("code",[t._v("SecurityWebFilterChain``@Bean")]),t._v("并通过"),i("code",[t._v("serverHttpSecurity.oauth2Login()")]),t._v("启用 OAuth2.0 登录。")])])]),t._v(" "),i("p",[t._v("如果需要根据你的特定需求重写自动配置,可以通过以下方式执行:")]),t._v(" "),i("ul",[i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-register-reactiveclientregistrationrepository-bean"}},[t._v("注册一个重新激活的注册存储库 @ Bean")])])]),t._v(" "),i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-register-securitywebfilterchain-bean"}},[t._v("注册一个 SecurityWebFilterchain@ Bean")])])]),t._v(" "),i("li",[i("p",[i("a",{attrs:{href:"#webflux-oauth2-login-completely-override-autoconfiguration"}},[t._v("完全覆盖自动配置")])])])]),t._v(" "),i("h3",{attrs:{id:"register-a-reactiveclientregistrationrepository-bean"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#register-a-reactiveclientregistrationrepository-bean"}},[t._v("#")]),t._v(" Register a ReactiveClientRegistrationRepository @Bean")]),t._v(" "),i("p",[t._v("下面的示例显示了如何注册"),i("code",[t._v("ReactiveClientRegistrationRepository``@Bean")]),t._v(":")]),t._v(" "),i("p",[t._v("爪哇")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@Configuration\npublic class OAuth2LoginConfig {\n\n\t@Bean\n\tpublic ReactiveClientRegistrationRepository clientRegistrationRepository() {\n\t\treturn new InMemoryReactiveClientRegistrationRepository(this.googleClientRegistration());\n\t}\n\n\tprivate ClientRegistration googleClientRegistration() {\n\t\treturn ClientRegistration.withRegistrationId("google")\n\t\t\t\t.clientId("google-client-id")\n\t\t\t\t.clientSecret("google-client-secret")\n\t\t\t\t.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n\t\t\t\t.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)\n\t\t\t\t.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")\n\t\t\t\t.scope("openid", "profile", "email", "address", "phone")\n\t\t\t\t.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")\n\t\t\t\t.tokenUri("https://www.googleapis.com/oauth2/v4/token")\n\t\t\t\t.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")\n\t\t\t\t.userNameAttributeName(IdTokenClaimNames.SUB)\n\t\t\t\t.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")\n\t\t\t\t.clientName("Google")\n\t\t\t\t.build();\n\t}\n}\n')])])]),i("p",[t._v("Kotlin")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@Configuration\nclass OAuth2LoginConfig {\n\n    @Bean\n    fun clientRegistrationRepository(): ReactiveClientRegistrationRepository {\n        return InMemoryReactiveClientRegistrationRepository(googleClientRegistration())\n    }\n\n    private fun googleClientRegistration(): ClientRegistration {\n        return ClientRegistration.withRegistrationId("google")\n                .clientId("google-client-id")\n                .clientSecret("google-client-secret")\n                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)\n                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")\n                .scope("openid", "profile", "email", "address", "phone")\n                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")\n                .tokenUri("https://www.googleapis.com/oauth2/v4/token")\n                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")\n                .userNameAttributeName(IdTokenClaimNames.SUB)\n                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")\n                .clientName("Google")\n                .build()\n    }\n}\n')])])]),i("h3",{attrs:{id:"register-a-securitywebfilterchain-bean"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#register-a-securitywebfilterchain-bean"}},[t._v("#")]),t._v(" Register a SecurityWebFilterChain @Bean")]),t._v(" "),i("p",[t._v("下面的示例显示了如何用"),i("code",[t._v("@EnableWebFluxSecurity")]),t._v("注册"),i("code",[t._v("SecurityWebFilterChain``@Bean")]),t._v("并通过"),i("code",[t._v("serverHttpSecurity.oauth2Login()")]),t._v("启用 OAuth2.0 登录:")]),t._v(" "),i("p",[t._v("例 2。OAuth2 登录配置")]),t._v(" "),i("p",[t._v("爪哇")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("@EnableWebFluxSecurity\npublic class OAuth2LoginSecurityConfig {\n\n\t@Bean\n\tpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {\n\t\thttp\n\t\t\t.authorizeExchange(authorize -> authorize\n\t\t\t\t.anyExchange().authenticated()\n\t\t\t)\n\t\t\t.oauth2Login(withDefaults());\n\n\t\treturn http.build();\n\t}\n}\n")])])]),i("p",[t._v("Kotlin")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v("@EnableWebFluxSecurity\nclass OAuth2LoginSecurityConfig {\n\n    @Bean\n    fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {\n        return http {\n            authorizeExchange {\n                authorize(anyExchange, authenticated)\n            }\n            oauth2Login { }\n        }\n    }\n}\n")])])]),i("h3",{attrs:{id:"完全覆盖自动配置"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#完全覆盖自动配置"}},[t._v("#")]),t._v(" 完全覆盖自动配置")]),t._v(" "),i("p",[t._v("下面的示例展示了如何通过注册一个"),i("code",[t._v("ReactiveClientRegistrationRepository``@Bean")]),t._v("和一个"),i("code",[t._v("SecurityWebFilterChain``@Bean")]),t._v("来完全覆盖自动配置。")]),t._v(" "),i("p",[t._v("例 3。覆盖自动配置")]),t._v(" "),i("p",[t._v("爪哇")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@EnableWebFluxSecurity\npublic class OAuth2LoginConfig {\n\n\t@Bean\n\tpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {\n\t\thttp\n\t\t\t.authorizeExchange(authorize -> authorize\n\t\t\t\t.anyExchange().authenticated()\n\t\t\t)\n\t\t\t.oauth2Login(withDefaults());\n\n\t\treturn http.build();\n\t}\n\n\t@Bean\n\tpublic ReactiveClientRegistrationRepository clientRegistrationRepository() {\n\t\treturn new InMemoryReactiveClientRegistrationRepository(this.googleClientRegistration());\n\t}\n\n\tprivate ClientRegistration googleClientRegistration() {\n\t\treturn ClientRegistration.withRegistrationId("google")\n\t\t\t\t.clientId("google-client-id")\n\t\t\t\t.clientSecret("google-client-secret")\n\t\t\t\t.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n\t\t\t\t.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)\n\t\t\t\t.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")\n\t\t\t\t.scope("openid", "profile", "email", "address", "phone")\n\t\t\t\t.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")\n\t\t\t\t.tokenUri("https://www.googleapis.com/oauth2/v4/token")\n\t\t\t\t.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")\n\t\t\t\t.userNameAttributeName(IdTokenClaimNames.SUB)\n\t\t\t\t.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")\n\t\t\t\t.clientName("Google")\n\t\t\t\t.build();\n\t}\n}\n')])])]),i("p",[t._v("Kotlin")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@EnableWebFluxSecurity\nclass OAuth2LoginConfig {\n\n    @Bean\n    fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {\n        return http {\n            authorizeExchange {\n                authorize(anyExchange, authenticated)\n            }\n            oauth2Login { }\n        }\n    }\n\n    @Bean\n    fun clientRegistrationRepository(): ReactiveClientRegistrationRepository {\n        return InMemoryReactiveClientRegistrationRepository(googleClientRegistration())\n    }\n\n    private fun googleClientRegistration(): ClientRegistration {\n        return ClientRegistration.withRegistrationId("google")\n                .clientId("google-client-id")\n                .clientSecret("google-client-secret")\n                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)\n                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")\n                .scope("openid", "profile", "email", "address", "phone")\n                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")\n                .tokenUri("https://www.googleapis.com/oauth2/v4/token")\n                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")\n                .userNameAttributeName(IdTokenClaimNames.SUB)\n                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")\n                .clientName("Google")\n                .build()\n    }\n}\n')])])]),i("h2",{attrs:{id:"不需要-spring-boot2-x-的-爪哇-配置"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#不需要-spring-boot2-x-的-爪哇-配置"}},[t._v("#")]),t._v(" 不需要 Spring boot2.x 的 爪哇 配置")]),t._v(" "),i("p",[t._v("如果你不能使用 Spring Boot2.x,并且希望在"),i("code",[t._v("CommonOAuth2Provider")]),t._v("中配置一个预定义的提供程序(例如,Google),请应用以下配置:")]),t._v(" "),i("p",[t._v("例 4。OAuth2 登录配置")]),t._v(" "),i("p",[t._v("Java")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@EnableWebFluxSecurity\npublic class OAuth2LoginConfig {\n\n\t@Bean\n\tpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {\n\t\thttp\n\t\t\t.authorizeExchange(authorize -> authorize\n\t\t\t\t.anyExchange().authenticated()\n\t\t\t)\n\t\t\t.oauth2Login(withDefaults());\n\n\t\treturn http.build();\n\t}\n\n\t@Bean\n\tpublic ReactiveClientRegistrationRepository clientRegistrationRepository() {\n\t\treturn new InMemoryReactiveClientRegistrationRepository(this.googleClientRegistration());\n\t}\n\n\t@Bean\n\tpublic ReactiveOAuth2AuthorizedClientService authorizedClientService(\n\t\t\tReactiveClientRegistrationRepository clientRegistrationRepository) {\n\t\treturn new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository);\n\t}\n\n\t@Bean\n\tpublic ServerOAuth2AuthorizedClientRepository authorizedClientRepository(\n\t\t\tReactiveOAuth2AuthorizedClientService authorizedClientService) {\n\t\treturn new AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository(authorizedClientService);\n\t}\n\n\tprivate ClientRegistration googleClientRegistration() {\n\t\treturn CommonOAuth2Provider.GOOGLE.getBuilder("google")\n\t\t\t\t.clientId("google-client-id")\n\t\t\t\t.clientSecret("google-client-secret")\n\t\t\t\t.build();\n\t}\n}\n')])])]),i("p",[t._v("Kotlin")]),t._v(" "),i("div",{staticClass:"language- extra-class"},[i("pre",{pre:!0,attrs:{class:"language-text"}},[i("code",[t._v('@EnableWebFluxSecurity\nclass OAuth2LoginConfig {\n\n    @Bean\n    fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {\n        return http {\n            authorizeExchange {\n                authorize(anyExchange, authenticated)\n            }\n            oauth2Login { }\n        }\n    }\n\n    @Bean\n    fun clientRegistrationRepository(): ReactiveClientRegistrationRepository {\n        return InMemoryReactiveClientRegistrationRepository(googleClientRegistration())\n    }\n\n    @Bean\n    fun authorizedClientService(\n        clientRegistrationRepository: ReactiveClientRegistrationRepository\n    ): ReactiveOAuth2AuthorizedClientService {\n        return InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository)\n    }\n\n    @Bean\n    fun authorizedClientRepository(\n        authorizedClientService: ReactiveOAuth2AuthorizedClientService\n    ): ServerOAuth2AuthorizedClientRepository {\n        return AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository(authorizedClientService)\n    }\n\n    private fun googleClientRegistration(): ClientRegistration {\n        return CommonOAuth2Provider.GOOGLE.getBuilder("google")\n                .clientId("google-client-id")\n                .clientSecret("google-client-secret")\n                .build()\n    }\n}\n')])])]),i("p",[i("RouterLink",{attrs:{to:"/spring-security/index.html"}},[t._v("OAuth2 登录")]),i("RouterLink",{attrs:{to:"/spring-security/advanced.html"}},[t._v("高级配置")])],1)])}),[],!1,null,null,null);e.default=r.exports}}]);