当前位置: 首页 > 工具软件 > OAuth2client > 使用案例 >

从 Spring security oauth2 client 自动配置中获取 AccessToken

帅彦
2023-12-01

问题

使用 Spring security oauth2 client 实现授权码模式,可以不用手动拼接url请求code和token等信息,用户登录成功之后可以在SuccessHandler中获取当前用户的信息。如果还想获取用户信息以外的授权资源,必须要有AccessToken,要怎么获取呢?先看下如何获取用户信息

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

配置文件

spring:
  security:
    oauth2:
      client:
        provider:
          github:
            authorization-uri: https://github.com/login/oauth/authorize
            token-uri: https://github.com/login/oauth/access_token
            user-info-uri: https://api.github.com/user
            user-name-attribute: id
        registration:
          demo:
            client-id: xxxxx
            client-secret: xxxxx
            client-name: oauth2-demo
            provider: github
            scope: profile
            redirect-uri: http://localhost:8080/oauth2/callback
            client-authentication-method: basic
            authorization-grant-type: authorization_code
  http:
    log-request-details: true

logging:
  level:
    root: info
    web: debug

配置类

package com.example.demo.configurations;

import com.example.demo.handler.Oauth2AuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private Oauth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler;

	@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2Login()
                .redirectionEndpoint()
                .baseUri("/oauth2/callback")
                .and()
				.successHandler(oauth2AuthenticationSuccessHandler)
        ;
    }
}

SuccessHandler

package com.example.demo.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Component
public class Oauth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    public Oauth2AuthenticationSuccessHandler() {
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException {
        OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
        if (oAuth2User != null) {
            log.info(oAuth2User.toString());
        }
        response.sendRedirect("/index.html");
    }
}

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>OAuth2 Demo</title>
    </head>
    <body>
        <p>已登录</p>
    </body>
</html>

分析

关键代码 OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal(); ,在 IDEA 中查找跟Authentication相关的类:OAuth2AuthenticationTokenOAuth2AuthorizedClient,然后百度,找到一个非常有用的spring security 官方文档:链接,得到解决方案:使用 @RegisteredOAuth2AuthorizedClien 注解,登录成功后访问 http://localhost:8080/token 即可看到 AccessToken

HelloController

package com.example.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@Slf4j
public class HelloController {
    @GetMapping("/token")
    @ResponseBody
    public String token(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
        return authorizedClient.getAccessToken().getTokenValue();
    }
}
 类似资料: