首页 > 其他分享 >Spring Authorization Server (三)客户端搭建

Spring Authorization Server (三)客户端搭建

时间:2023-07-19 19:05:25浏览次数:34  
标签:Spring Server token client spring oauth server Authorization 客户端

在上一篇中,我们介绍了认证服务器的搭建,由于我们没有自己的客户端回调地址,在测试过程中,我们是使用http://www.baidu.com作为回调地址,获取到授权码code后,再使用postman去获取令牌信息的。在本篇中,我们将搭建自己的客户端,实现连贯的令牌获取操作, 操作流程如下。

Spring Authorization Server (三)客户端搭建_Spring Boot3

场景类比

假设我们公司的web平台产品支持微信登录,那么对于微信平台来说,我们的web平台就是客户端(第三方),那么,首先我们就得需要在微信开发者平台中注册客户端信息,例如:申请客户端id(client_id,微信平台叫appId)、密钥(secret)、配置授权码回调地址等。上一篇我们搭建的工程spring-oauth-server就类似微信平台的认证服务器,我们接下来要搭建的客户端工程叫spring-oauth-client就类似公司的web平台。

客户端搭建

在spring-oauth-parent父工程下,创建spring-oauth-client子工程,添加spring-boot-starter-oauth2-client依赖,由于此处与Spring Authorization Server框架无关,可不用必须使用SpringBoot3,但为了版本统一,在此还是继续使用父工程中的SpringBoot3。

pom.xml添加依赖如下。

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.oauth</groupId>
        <artifactId>spring-oauth-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>spring-oauth-client</artifactId>
    <name>客户端</name>

    <dependencies>
        <!--spring-boot-starter-oauth2-client-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <!--spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  
</project>

     application.yml配置如下

server:
  port: 9001

logging:
  level:
    org.springframework.security: trace

spring:
  application:
    name: spring-oauth-client
  security:
    oauth2:
      client:
        provider:
          #认证服务器信息
          oauth-server:
            #授权地址
            issuer-uri: http://spring-oauth-server:9000
            authorizationUri: ${spring.security.oauth2.client.provider.oauth-server.issuer-uri}/oauth2/authorize
            #令牌获取地址
            tokenUri: ${spring.security.oauth2.client.provider.oauth-server.issuer-uri}/oauth2/token
        registration:
          messaging-client-oidc:
            #认证提供者,标识由哪个认证服务器进行认证,和上面的oauth-server进行关联
            provider: oauth-server
            #客户端名称
            client-name: web平台
            #客户端id,从认证平台申请的客户端id
            client-id: web-client-id
            #客户端秘钥
            client-secret: secret
            #客户端认证方式
            client-authentication-method: client_secret_basic
            #使用授权码模式获取令牌(token)
            authorization-grant-type: authorization_code
            #回调地址,接收认证服务器回传code的接口地址,之前我们是使用http://www.baidu.com代替
            redirect-uri: http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc
            scope:
              - profile
              - openid

注意:上面配置中出现两个域名,分别是spring-oauth-client、spring-oauth-server,因为我是在同一台机器上进行启动客户端和认证服务器的,ip都是127.0.0.1,在ip相同的情况下,会出现cookie覆盖的情形,这会导致认证服务器重定向到客户端地址时会出现[authorization_request_not_found]异常,为解决这个问题,本人在C:\Windows\System32\drivers\etc目录下的hosts文件添加了一行IP域名映射,即127.0.0.1 spring-oauth-client spring-oauth-server。

启动类如下。

@SpringBootApplication
public class SpringOauthClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringOauthClientApplication.class,args);
    }
}

客户端信息表oauth2_registered_client增加下面一条客户端记录。

INSERT INTO `oauth-server`.`oauth2_registered_client` (`id`, `client_id`, `client_id_issued_at`, `client_secret`, `client_secret_expires_at`, `client_name`, `client_authentication_methods`, `authorization_grant_types`, `redirect_uris`, `post_logout_redirect_uris`, `scopes`, `client_settings`, `token_settings`) VALUES ('3eacac0e-0de9-4727-9a64-6bdd4be2ee1g', 'web-client-id', '2023-07-12 07:33:42', '$2a$10$.J0Rfg7y2Mu8AN8Dk2vL.eBFa9NGbOYCPOAFEw.QhgGLVXjO7eFDC', NULL, 'web平台', 'client_secret_basic', 'refresh_token,authorization_code', 'http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc', 'http://127.0.0.1:9000/', 'openid,profile', '{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-proof-key\":false,\"settings.client.require-authorization-consent\":true}', '{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.token.reuse-refresh-tokens\":true,\"settings.token.id-token-signature-algorithm\":[\"org.springframework.security.oauth2.jose.jws.SignatureAlgorithm\",\"RS256\"],\"settings.token.access-token-time-to-live\":[\"java.time.Duration\",300.000000000],\"settings.token.access-token-format\":{\"@class\":\"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat\",\"value\":\"self-contained\"},\"settings.token.refresh-token-time-to-live\":[\"java.time.Duration\",3600.000000000],\"settings.token.authorization-code-time-to-live\":[\"java.time.Duration\",300.000000000],\"settings.token.device-code-time-to-live\":[\"java.time.Duration\",300.000000000]}');

新建AuthenticationController类,代码如下。

@RestController
public class AuthenticationController {

    @GetMapping("/token")
    @ResponseBody
    public OAuth2AuthorizedClient token(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient) {
        return oAuth2AuthorizedClient;
    }
}

客户端工程结构如下。

Spring Authorization Server (三)客户端搭建_客户端_02

客户端测试

启动认证服务器和客户端服务,浏览器输入http://spring-oauth-client:9001/token地址发起接口访问。

Spring Authorization Server (三)客户端搭建_客户端_03

此时我们看到,浏览器地址已被重定向到认证服务器http://spring-oauth-server:9000/login中被要求进行登录,

Spring Authorization Server (三)客户端搭建_OpenID Connect 1.0_04

输入用户在认证服务器的用户名:user,密码:123456,则跳转到认证服务器授权页面,

Spring Authorization Server (三)客户端搭建_OAuth2.1_05

勾选授权信息profile,点击提交按钮,则返回如下结果。

Spring Authorization Server (三)客户端搭建_Spring Security_06

此时我们看到了浏览器中的地址为http://spring-oauth-client:9001/token?continue,且返回了客户端及token信息。也看到了认证服务器将授权码拼接到了回调地址http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc中传给客户端。

页面json数据如下。

{
    "clientRegistration":{
        "registrationId":"messaging-client-oidc",
        "clientId":"web-client-id",
        "clientSecret":"secret",
        "clientAuthenticationMethod":{
            "value":"client_secret_basic"
        },
        "authorizationGrantType":{
            "value":"authorization_code"
        },
        "redirectUri":"http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc",
        "scopes":[
            "profile",
            "openid"
        ],
        "providerDetails":{
            "authorizationUri":"http://spring-oauth-server:9000/oauth2/authorize",
            "tokenUri":"http://spring-oauth-server:9000/oauth2/token",
            "userInfoEndpoint":{
                "uri":"http://spring-oauth-server:9000/userinfo",
                "authenticationMethod":{
                    "value":"header"
                },
                "userNameAttributeName":"sub"
            },
            "jwkSetUri":"http://spring-oauth-server:9000/oauth2/jwks",
            "issuerUri":"http://spring-oauth-server:9000",
            "configurationMetadata":{
                "authorization_endpoint":"http://spring-oauth-server:9000/oauth2/authorize",
                "token_endpoint":"http://spring-oauth-server:9000/oauth2/token",
                "introspection_endpoint":"http://spring-oauth-server:9000/oauth2/introspect",
                "revocation_endpoint":"http://spring-oauth-server:9000/oauth2/revoke",
                "device_authorization_endpoint":"http://spring-oauth-server:9000/oauth2/device_authorization",
                "issuer":"http://spring-oauth-server:9000",
                "jwks_uri":"http://spring-oauth-server:9000/oauth2/jwks",
                "scopes_supported":[
                    "openid"
                ],
                "response_types_supported":[
                    "code"
                ],
                "grant_types_supported":[
                    "authorization_code",
                    "client_credentials",
                    "refresh_token",
                    "urn:ietf:params:oauth:grant-type:device_code"
                ],
                "token_endpoint_auth_methods_supported":[
                    "client_secret_basic",
                    "client_secret_post",
                    "client_secret_jwt",
                    "private_key_jwt"
                ],
                "introspection_endpoint_auth_methods_supported":[
                    "client_secret_basic",
                    "client_secret_post",
                    "client_secret_jwt",
                    "private_key_jwt"
                ],
                "revocation_endpoint_auth_methods_supported":[
                    "client_secret_basic",
                    "client_secret_post",
                    "client_secret_jwt",
                    "private_key_jwt"
                ],
                "request_uri_parameter_supported":true,
                "subject_types_supported":[
                    "public"
                ],
                "userinfo_endpoint":"http://spring-oauth-server:9000/userinfo",
                "end_session_endpoint":"http://spring-oauth-server:9000/connect/logout",
                "id_token_signing_alg_values_supported":[
                    "RS256"
                ]
            }
        },
        "clientName":"web平台"
    },
    "principalName":"user",
    "accessToken":{
        "tokenValue":"eyJraWQiOiIyYzZlOTdkNi01NzhjLTQ3NWYtYmYzNy1lMDljODY3OWUyYzAiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiYXVkIjoid2ViLWNsaWVudC1pZCIsIm5iZiI6MTY4OTI0NTM2NSwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSJdLCJpc3MiOiJodHRwOi8vc3ByaW5nLW9hdXRoLXNlcnZlcjo5MDAwIiwiZXhwIjoxNjg5MjQ1NjY1LCJpYXQiOjE2ODkyNDUzNjV9.dBIkteklddxt6BFFalMi11fjk1t_9gA034jeO3vbcGPadCjpM46AxUAolH3mD98d-mCVlwzl1enFtFfvHdJEBB4LbGMwBfvDHUXK6ODk3rNwU_I8pIOq2AG9cErSnnRBMSAVsz421UnXL_bcITM1iYSZmhkiRxyg4JwZLN1h-4H35RsjqU1IBYappPNPeH7P7DzbIQ10M58gieajyII0oU90ksgPf4J3sy3FMQG29WAe1Mtul5W1lP-eLhTYStnHH8FJxFIrJMO2kTv2T7pP2OUDBIBSxU7KORACVhr74xWmIzuMa9Ue3anI34JIn4hicSsnoq-EmHv03pFSRlKbYQ",
        "issuedAt":"2023-07-13T10:49:25.091674300Z",
        "expiresAt":"2023-07-13T10:54:24.091674300Z",
        "tokenType":{
            "value":"Bearer"
        },
        "scopes":[
            "openid",
            "profile"
        ]
    },
    "refreshToken":{
        "tokenValue":"1Ed1_Y8vrxGjnz-v-9CNG6-iP1fyPOo1bll3UMhNNFzY5R8ODENRIiBfqoZHKx4t9eg-B43aOmoO-x8ca8UdQqwQB35i40CHhp4GsekkyDYQ51F5hUUeM_0LdQYlI9sC",
        "issuedAt":"2023-07-13T10:49:25.091674300Z",
        "expiresAt":null
    }
}

注意:在上面的测试中,我们通过OAuth2AuthorizedClient对象获取到客户端和令牌相关的信息,然后直接返回给前端页面,在实际应用中,要根据实际需要,返回适当的字段。

总结

本文简单介绍了oauth2客户端的搭建及测试,客户端的主要职责是识别用户操作是否有身份认证,已认证,则放行,未认证,则拒绝或引导到认证服务器进行认证。到此,一个简单的客户端就此搭建完成。

标签:Spring,Server,token,client,spring,oauth,server,Authorization,客户端
From: https://blog.51cto.com/u_15268610/6779127

相关文章

  • spring cloud stream RabbitMQ实践
    上一篇文章介绍了《springcloudstreamkafka实践》提到springcloud封装了消息中间件,只需要简单修改配置就可以切换消息中间件。在kafka的基础上,切换到rabbitmq。一、配置依赖1<dependency>2<groupId>org.springframework.cloud</groupId>3<artifactId......
  • 怎么查看sql server数据库登录密码
    如何查看SQLServer数据库登录密码要查看SQLServer数据库登录密码,需要使用系统存储过程和DMV(DynamicManagementViews)来查询相关信息。下面是一个详细的步骤说明,以及相应的代码示例。步骤1:连接到SQLServer实例首先,使用SQLServerManagementStudio(SSMS)或其他SQLServer数据......
  • springcloud stream kafka实践
    SpringCloudStream是SpringCloud提供的一个用于构建消息驱动的微服务的框架。它简化了消息系统(如Kafka,rabbitMQ)的使用和集成,使开发者可以更专注于业务逻辑的实现。项目结构如下 一、移入依赖创建一个springbootweb项目引入依赖1<properties>2<java.version>1......
  • springboot——yaml格式
    ......
  • spring事务
    Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的try…catch…finally代码。我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性......
  • struts与spring集成
    1.struts与spring集成Spring和struts整合的四种方式。1.使用Spring的ActionSupport2.使用Spring的DelegatingRequestProcessor类。3.全权委托。org.springframework.web.struts.DelegatingActionProxy4.使用org.springframework.web.struts.AutowiringRequestProcessor......
  • 活动回顾丨阿里云 Serverless 技术实战与创新广州站回放& PPT 下载
    7月8日“阿里云Serverless技术实战与创新”广州站圆满落幕。活动受众以关注Serverless技术的开发者、企业决策人、云原生领域创业者为主,活动形式为演讲、动手实操,让开发者通过一个下午的时间增进对Serverless技术的理解,快速上手Serverless,拥抱云计算新范式带来的技术红......
  • springboot
    起步依赖这两个包的源码:第一个:<developers><developer><name>Pivotal</name><email>[email protected]</email><organization>PivotalSoftware,Inc.</organization><organizationUrl>https://www.sprin......
  • 转:springboot2.0 集成redis服务详解,以及 (Lettuce & Jedis)
    springboot2.0集成redis服务详解,以及(Lettuce&Jedis)   ......
  • 活动回顾丨阿里云 Serverless 技术实战与创新广州站回放& PPT 下载
    7月8日“阿里云Serverless技术实战与创新”广州站圆满落幕。活动受众以关注Serverless技术的开发者、企业决策人、云原生领域创业者为主,活动形式为演讲、动手实操,让开发者通过一个下午的时间增进对Serverless技术的理解,快速上手Serverless,拥抱云计算新范式带来的技术......