如何将 Spring Boot 与 Spotify OAuth 2 身份验证集成
How to integrate Spring Boot with Spotify OAuth 2 authentication
我是 spring 引导和 spring 安全方面的新手。所以我从一些教程开始。现在我想在我的示例应用程序中将 oauth 身份验证与 spotify 集成。
我在 spring.io 的 spring boot oauth 2 教程中指导了我。将解释我如何将 oauth 与 facebook 和 github 集成。我自定义了 application.yml 来 spotify 配置,但它没有用。
application.yml
security:
oauth2:
client:
clientId: <my-client-id>
clientSecret: <my-secret>
accessTokenUri: https://accounts.spotify.com/api/token
userAuthorizationUri: https://accounts.spotify.com/authorize
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
scope: user-read-private, user-read-email
resource:
userInfoUri: https://api.spotify.com/v1/me
SpotifyOAuthApplication.java
package sh.stern.SpotifyOAuth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class SpotifyOAuthApplication extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(SpotifyOAuthApplication.class, args);
}
@RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**", "/error**")
.permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
/resources/static/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Demo</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width"/>
<base href="/"/>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Demo</h1>
<div class="container">
<div class="container unauthenticated">
With Spotify: <a href="/login">click here</a>
</div>
<div class="container authenticated" style="display:none">
Logged in as: <span id="user"></span>
<div>
<button onClick="logout()" class="btn btn-primary">Logout</button>
</div>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.userAuthentication.details.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
var logout = function() {
$.post("/logout", function() {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
});
return true;
}
$.ajaxSetup({
beforeSend : function(xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT'
|| settings.type == 'DELETE') {
if (!(/^http:.*/.test(settings.url) || /^https:.*/
.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-XSRF-TOKEN",
Cookies.get('XSRF-TOKEN'));
}
}
}
});
</script>
<script type="text/javascript" src="/webjars/js-cookie/js.cookie.js"></script>
</div>
</body>
</html>
build.gradle
plugins {
id 'org.springframework.boot' version '2.1.5.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'sh.stern'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
compile group: 'org.springframework.security.oauth.boot', name: 'spring-security-oauth2-autoconfigure', version: '2.1.5.RELEASE'
compile group: 'org.webjars', name: 'jquery', version: '3.4.1'
compile group: 'org.webjars', name: 'js-cookie', version: '2.1.0'
compile group: 'org.webjars', name: 'bootstrap', version: '4.3.1'
compile group: 'org.webjars', name: 'webjars-locator-core', version: '0.37'
}
如果我启动我的应用程序并在 localhost:8080 上打开 Web 应用程序,我将被重定向到 Spotify。我登录到我的 spotify 帐户并被重定向到我的应用程序,但在重定向后我收到以下错误:
2019-05-24 23:00:17.564 WARN 55176 --- [io-8080-exec-10] o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class org.springframework.web.client.HttpClientErrorException$Unauthorized, 401 Unauthorized
我是否配置错误 application.yml?
我能找到问题所在,application.yml 配置错误。似乎 tokenName 是错误的。我删除了这个属性,现在它可以工作了。
配置现在看起来像这样:
security:
oauth2:
client:
clientId: <my-client-id>
clientSecret: <my-client-secret>
accessTokenUri: https://accounts.spotify.com/api/token
userAuthorizationUri: https://accounts.spotify.com/authorize
authenticationScheme: query
clientAuthenticationScheme: form
scope: user-read-private, user-read-email
resource:
userInfoUri: https://api.spotify.com/v1/me
我是 spring 引导和 spring 安全方面的新手。所以我从一些教程开始。现在我想在我的示例应用程序中将 oauth 身份验证与 spotify 集成。
我在 spring.io 的 spring boot oauth 2 教程中指导了我。将解释我如何将 oauth 与 facebook 和 github 集成。我自定义了 application.yml 来 spotify 配置,但它没有用。
application.yml
security:
oauth2:
client:
clientId: <my-client-id>
clientSecret: <my-secret>
accessTokenUri: https://accounts.spotify.com/api/token
userAuthorizationUri: https://accounts.spotify.com/authorize
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
scope: user-read-private, user-read-email
resource:
userInfoUri: https://api.spotify.com/v1/me
SpotifyOAuthApplication.java
package sh.stern.SpotifyOAuth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class SpotifyOAuthApplication extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(SpotifyOAuthApplication.class, args);
}
@RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**", "/error**")
.permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
/resources/static/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Demo</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width"/>
<base href="/"/>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Demo</h1>
<div class="container">
<div class="container unauthenticated">
With Spotify: <a href="/login">click here</a>
</div>
<div class="container authenticated" style="display:none">
Logged in as: <span id="user"></span>
<div>
<button onClick="logout()" class="btn btn-primary">Logout</button>
</div>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.userAuthentication.details.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
var logout = function() {
$.post("/logout", function() {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
});
return true;
}
$.ajaxSetup({
beforeSend : function(xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT'
|| settings.type == 'DELETE') {
if (!(/^http:.*/.test(settings.url) || /^https:.*/
.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-XSRF-TOKEN",
Cookies.get('XSRF-TOKEN'));
}
}
}
});
</script>
<script type="text/javascript" src="/webjars/js-cookie/js.cookie.js"></script>
</div>
</body>
</html>
build.gradle
plugins {
id 'org.springframework.boot' version '2.1.5.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'sh.stern'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
compile group: 'org.springframework.security.oauth.boot', name: 'spring-security-oauth2-autoconfigure', version: '2.1.5.RELEASE'
compile group: 'org.webjars', name: 'jquery', version: '3.4.1'
compile group: 'org.webjars', name: 'js-cookie', version: '2.1.0'
compile group: 'org.webjars', name: 'bootstrap', version: '4.3.1'
compile group: 'org.webjars', name: 'webjars-locator-core', version: '0.37'
}
如果我启动我的应用程序并在 localhost:8080 上打开 Web 应用程序,我将被重定向到 Spotify。我登录到我的 spotify 帐户并被重定向到我的应用程序,但在重定向后我收到以下错误:
2019-05-24 23:00:17.564 WARN 55176 --- [io-8080-exec-10] o.s.b.a.s.o.r.UserInfoTokenServices : Could not fetch user details: class org.springframework.web.client.HttpClientErrorException$Unauthorized, 401 Unauthorized
我是否配置错误 application.yml?
我能找到问题所在,application.yml 配置错误。似乎 tokenName 是错误的。我删除了这个属性,现在它可以工作了。
配置现在看起来像这样:
security:
oauth2:
client:
clientId: <my-client-id>
clientSecret: <my-client-secret>
accessTokenUri: https://accounts.spotify.com/api/token
userAuthorizationUri: https://accounts.spotify.com/authorize
authenticationScheme: query
clientAuthenticationScheme: form
scope: user-read-private, user-read-email
resource:
userInfoUri: https://api.spotify.com/v1/me