如何使用Google作为认证方配置Spring Boot 2 Security5集成的OAuth2登录我们自己的工程项目------范例1

Google客户端授权生成client-id和client-secret我们需要登录以下地址
https://console.developers.google.com

第1部分:

范例工程项目结构如下:

Enabling OAuth 2 login

Suppose that you want to enable users of your application to be able to sign in with Google. With Spring Security 5, it couldn’t be any easier. All you need to do is add Spring Security’s OAuth 2 client support to your project’s build and then configure your application’s Google credentials.

First, add the Spring Security OAuth 2 client library to your Spring Boot project’s build, along with the Spring Security starter dependency:

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

/opt/coding/spring-boot2-oauth2-security5/src/main/java/com/contoso/Application.java

package com.contoso;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

/opt/coding/spring-boot2-oauth2-security5/src/main/java/com/contoso/api/OAuth2Controller.java

package com.contoso.api;

import java.util.Collections;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;

import reactor.core.publisher.Mono;

@Controller
public class OAuth2Controller {

	@Autowired
	private OAuth2AuthorizedClientService authorizedClientService;
	
	@RequestMapping("/")
	public String index(Model model, OAuth2AuthenticationToken authentication) {
		OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient(authentication);
		model.addAttribute("userName", authentication.getName());
		model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());
		return "index";
	}

	private OAuth2AuthorizedClient getAuthorizedClient(OAuth2AuthenticationToken authentication) {
		return this.authorizedClientService.loadAuthorizedClient(
			authentication.getAuthorizedClientRegistrationId(), authentication.getName());
    }
	
	@RequestMapping("/userinfo")
	public String userinfo(Model model,OAuth2AuthenticationToken authentication) {
		// authentication.getAuthorizedClientRegistrationId() returns the
		// registrationId of the Client that was authorized during the Login flow
		OAuth2AuthorizedClient authorizedClient =
			this.authorizedClientService.loadAuthorizedClient(
				authentication.getAuthorizedClientRegistrationId(),authentication.getName());
		OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
		System.out.println(accessToken.getTokenValue());
		Map userAttributes = Collections.emptyMap();
		String userInfoEndpointUri = authorizedClient.getClientRegistration()
			.getProviderDetails().getUserInfoEndpoint().getUri();
		if (!StringUtils.isEmpty(userInfoEndpointUri)) {// userInfoEndpointUri is optional for OIDC Clients
			userAttributes = WebClient.builder()
				.filter(oauth2Credentials(authorizedClient))
				.build().get().uri(userInfoEndpointUri).retrieve().bodyToMono(Map.class).block();
		}
		model.addAttribute("userAttributes", userAttributes);
		return "userinfo";
	}
	
	private ExchangeFilterFunction oauth2Credentials(OAuth2AuthorizedClient authorizedClient) {
		return ExchangeFilterFunction.ofRequestProcessor(
			clientRequest -> {
			ClientRequest authorizedRequest = ClientRequest.from(clientRequest)
			.header(HttpHeaders.AUTHORIZATION, "Bearer " + 
			authorizedClient.getAccessToken().getTokenValue()).build();
			return Mono.just(authorizedRequest);
		});
    }
}

/opt/coding/spring-boot2-oauth2-security5/src/main/java/com/contoso/config/OAuth2LoginConfig.java

package com.contoso.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class OAuth2LoginConfig {

	@EnableWebSecurity
	public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http
				.authorizeRequests()
				.anyRequest().authenticated()
				.and()
				.oauth2Login();
		}
	}

}

application.yml

server:
  port: 8080

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
#    org.springframework.boot.autoconfigure: DEBUG

spring:
  thymeleaf:
    cache: false
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: 212269349981-v8oa5coeuali2tufmh0nm41q9k6geet7.apps.googleusercontent.com
            client-secret: CqLWmSzFg83Jj-MyAtRVkUH6
            client-authentication-method: basic
            authorization-grant-type: authorization_code
            redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
            scope: openid, profile, email, address, phone
            client-name: Google Login
        provider: 
          google:   
            authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
            token-uri: https://www.googleapis.com/oauth2/v4/token
            user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
            jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs
            user-name-attribute: sub

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
	<title>Spring Security - OAuth2 Login</title>
	<meta charset="utf-8" />
</head>
<body>
<div style="float: right" th:fragment="logout" sec:authorize="isAuthenticated()">
	<div style="float:left">
		<span style="font-weight:bold">User: </span><span sec:authentication="name"></span>
	</div>
	<div style="float:none">&nbsp;</div>
	<div style="float:right">
		<form action="#" th:action="@{/logout}" method="post">
			<input type="submit" value="Logout" />
		</form>
	</div>
</div>
<h1>OAuth2 Login with Spring Security</h1>
<div>
	You are successfully logged in <span style="font-weight:bold" th:text="${userName}"></span>
	via the OAuth2 Client <span style="font-weight:bold" th:text="${clientName}"></span>
</div>
<div>&nbsp;</div>
<div>
	<a href="/userinfo" th:href="@{/userinfo}">Display User Information</a>
</div>
</body>
</html>

userinfo.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
	<title>Spring Security - OAuth2 User Information</title>
	<meta charset="utf-8" />
</head>
<body>
<div th:substituteby="index::logout"></div>
<h1>OAuth2 User Information</h1>
<div>
	<span style="font-weight:bold">User Attributes:</span>
	<ul>
		<li th:each="userAttribute : ${userAttributes}">
			<span style="font-weight:bold" th:text="${userAttribute.key}"></span>: 
			<span th:text="${userAttribute.value}"></span>
		</li>
	</ul>
</div>
</body>
</html>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.contoso</groupId>
	<artifactId>spring-boot2-oauth2-security5</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot2-oauth2-security5</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.4.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity4</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-oauth2-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-oauth2-jose</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>io.projectreactor</groupId>
			<artifactId>reactor-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

</project>

第2部分:

只保留application.yml以下部分使用同样的方式登录,一样可以获得Google上注册时填写的个人信息

第3部分:

使用Java代码替代application.yml配置文件方式实现同样的效果,application.yml配置文件内容如下:

server:
  port: 8080

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
#    org.springframework.boot.autoconfigure: DEBUG

spring:
  thymeleaf:
    cache: false

/opt/coding/spring-boot2-oauth2-security5/src/main/java/com/contoso/config/OAuth2LoginConfig.java

package com.contoso.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;

@Configuration
public class OAuth2LoginConfig {

	@EnableWebSecurity
	public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http
				.authorizeRequests()
				.anyRequest().authenticated()
				.and()
				.oauth2Login();
		}
	}
	

	@Bean
	public ClientRegistrationRepository clientRegistrationRepository() {
		return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
	}
	
	private ClientRegistration googleClientRegistration() {
		return ClientRegistration.withRegistrationId("google")
			.clientId("212269349981-v8oa5coeuali2tufmh0nm41q9k6geet7.apps.googleusercontent.com")
			.clientSecret("CqLWmSzFg83Jj-MyAtRVkUH6")
			.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
			.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
			.redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
			.scope("openid", "profile", "email", "address", "phone")
			.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
			.tokenUri("https://www.googleapis.com/oauth2/v4/token")
			.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
			.userNameAttributeName(IdTokenClaimNames.SUB)
			.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
			.clientName("Google Login")
			.build();
	}

}

猜你喜欢

转载自blog.csdn.net/zhengzizhi/article/details/81590687
今日推荐