12-SpringSecurity:通过OAuth2集成Github登录

@GetMapping(value = “/user/reg”)

public String registration() {

ClientRegistration githubRegistration = this.clientRegistrationRepository.findByRegistrationId(“github”);

log.info(githubRegistration.toString());

return githubRegistration.toString();

}

访问之后会返回 registration 信息,其中包含了 clientIdclientSecretauthorizationGrantTyperedirectUriscopes 等。

2021-01-20-GithubRegistration.png

实验2:查看获取到的AccessToken

@GetMapping(value = “/user/token”)

public OAuth2AccessToken accessToken(OAuth2AuthenticationToken authentication) {

OAuth2AuthorizedClient authorizedClient = this.authorizedClientService.loadAuthorizedClient(

authentication.getAuthorizedClientRegistrationId(), authentication.getName());

OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

return accessToken;

}

2021-01-20-Token.png

Note: 这里的 issuedAtexpiresAt 着实诡异,仅差了一秒,是Github授权服务问题?还没细看是什么原因。。

实验3:通过AccessToken请求Github的API

定义抽象 API 绑定类,通过拦截器将获取到的 AccessToken 设置到后续请求头中,通过 RestTemplate 实现对 API 的请求:

public abstract class ApiBinding {

protected RestTemplate restTemplate;

public ApiBinding(String accessToken) {

this.restTemplate = new RestTemplate();

if (accessToken != null) {

this.restTemplate.getInterceptors().add(getBearerTokenInterceptor(accessToken));

} else {

this.restTemplate.getInterceptors().add(getNoTokenInterceptor());

}

}

private ClientHttpRequestInterceptor getBearerTokenInterceptor(String accessToken) {

return new ClientHttpRequestInterceptor() {

@Override

public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {

request.getHeaders().add(“Authorization”, "Bearer " + accessToken);

return execution.execute(request, bytes);

}

};

}

private ClientHttpRequestInterceptor getNoTokenInterceptor() {

return new ClientHttpRequestInterceptor() {

@Override

public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {

throw new IllegalStateException(“Can’t access the Github API without an access token”);

}

};

}

}

将获取 AccessToken 的过程进行封装:

@Configuration

@Slf4j

public class SocialConfig {

@Bean

@RequestScope

public Github github(OAuth2AuthorizedClientService clientService) {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

String accessToken = null;

if (authentication.getClass().isAssignableFrom(OAuth2AuthenticationToken.class)) {

OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;

String clientRegistrationId = oauthToken.getAuthorizedClientRegistrationId();

if (clientRegistrationId.equals(“github”)) {

OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(clientRegistrationId, oauthToken.getName());

if (client != null) {

accessToken = client.getAccessToken().getTokenValue();

}

log.info(accessToken);

}

}

return new Github(accessToken);

}

}

public class Github extends ApiBinding {

private static final String BASE_URL = “https://api.github.com”;

public Github(String accessToken) {

super(accessToken);

}

public String getProfile() {

return restTemplate.getForObject(BASE_URL + “/user”, String.class);

}

}

Controller 中新增接口:通过 AccessToken 获取 Github 用户信息:

@GetMapping(value = “/user/info”)

public String info() {

String profile = github.getProfile();

log.info(github.getProfile());

return profile;

}

2021-01-20-UserInfo.png

Note:两个接口的区别:https://api.github.com/users/heartsuit(无需认证),https://api.github.com/user(需要认证)

2021-01-20-APICompare.png

Controller 的完整代码:

@RestController

@Slf4j

public class HelloController {

@Autowired

private ClientRegistrationRepository clientRegistrationRepository;

@Autowired

private OAuth2AuthorizedClientService authorizedClientService;

@Autowired

Github github;

@GetMapping(value = “/”)

public String index() {

log.info(SecurityContextHolder.getContext().getAuthentication().toString());

return "Welcome " + SecurityContextHolder.getContext().getAuthentication();

}

@GetMapping(value = “/user/reg”)

public String registration() {

ClientRegistration githubRegistration = this.clientRegistrationRepository.findByRegistrationId(“github”);

log.info(githubRegistration.toString());

return githubRegistration.toString();

}

@GetMapping(value = “/user/token”)

public OAuth2AccessToken accessToken(OAuth2AuthenticationToken authentication) {

OAuth2AuthorizedClient authorizedClient = this.authorizedClientService.loadAuthorizedClient(

authentication.getAuthorizedClientRegistrationId(), authentication.getName());

OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

return accessToken;

}

@GetMapping(value = “/user/info”)

public String info() {

String profile = github.getProfile();

log.info(github.getProfile());

return profile;

}

}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Spring Security中实现第三方登录,可以使用Gitee作为示例。下面是实现的步骤: 1. 在Gitee上创建应用并获取相应的客户端ID和客户端秘钥。 2. 在Spring Boot项目中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> ``` 3. 在`application.yml`或`application.properties`文件中配置Gitee的相关信息: ```yaml spring: security: oauth2: client: registration: gitee: clientId: <your_client_id> clientSecret: <your_client_secret> redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" clientName: Gitee provider: gitee: authorizationUri: https://gitee.com/oauth/authorize tokenUri: https://gitee.com/oauth/token userInfoUri: https://gitee.com/api/v5/user userNameAttribute: name ``` 4. 创建一个登录控制器处理授权回调和获取用户信息: ```java @Controller public class LoginController { @GetMapping("/login") public String login() { return "login"; } @GetMapping("/login/oauth2/code/gitee") public String loginPage(HttpServletRequest request) { return "redirect:/oauth2/authorization/gitee"; } @GetMapping("/loginSuccess") public String loginSuccess() { return "success"; } } ``` 5. 创建一个自定义用户信息服务类: ```java @Service public class CustomOAuth2UserService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); // 获取用户信息 // 可以在这里将用户信息存储到数据库或进行其他操作 return oAuth2User; } } ``` 6. 在配置类中配置`CustomOAuth2UserService`: ```java @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomOAuth2UserService customOAuth2UserService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/login**") .permitAll() .anyRequest() .authenticated() .and() .oauth2Login() .userInfoEndpoint() .userService(customOAuth2UserService); } } ``` 7. 创建登录页面 (`login.html`) 和登录成功页面 (`success.html`)。 现在,你可以通过访问 `/login` 来启动第三方登录流程了。选择 Gitee 作为登录方式并进行授权后,用户将被重定向到 `/loginSuccess` 页面。 请注意,以上只是一个简单的示例。实际情况中,你可能需要根据你的需求进行更多的配置和适配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值