Spring OAuth 2.0 客户端 returns 输入正确凭据后出现 401 未授权
Spring OAuth 2.0 Client returns 401 Unauthorized after entering correct credentials
这是我的问题。
我正在尝试使用 springboot 集成 dexcom rest api 来获取用户健康数据。
由 dexcom api 使用 oauth2 流程。
当我点击 link /login 应用程序重定向到 dexcom api 登录页面并询问用户
用户名和密码如果身份验证成功,dexcom 登录页面将重定向到我的
应用程序通过使用此授权发送授权代码重定向 uri 我需要从 dexcom 获取访问令牌,后来我使用 dexcom 获取数据 api.This 是我的项目
我的问题是,在 dexcom 登录页面成功输入用户名和密码后,通过提供授权码验证并重定向到我的应用程序,
http://localhost:8080/login?code=c956626ef691a1abe46bcc827a68ddfb&state=lJCK1p
但在同一页面中,我遇到了以下错误
enter image description here
白标错误页面
此应用程序没有 /error 的显式映射,因此您将其视为后备。
2021 年 6 月 8 日星期二 20:52:24IST
出现意外错误(类型=未授权,状态=401)。
我的代码
package com.example.mystorageapp;
@RestController
@EnableWebSecurity
@EnableOAuth2Sso
public class Dexomapi extends WebSecurityConfigurerAdapter {
//@SuppressWarnings("deprecation")
@GetMapping(value="/login")
public Response get_auth(@RequestParam(value="code",required =false) String code,
@RequestParam(value="state") String state ) throws IOException {
RestTemplate ss=new RestTemplate();
OkHttpClient client = new OkHttpClient();
String client1= (String)"client_secret=t2sI8N7eY3dW50GK&
client_id=XXXXXXXX&code="+code+"&grant_type=
authorization_code&redirect_uri=http://localhost:8080/login";
System.out.println(code);
String data23="https://api.dexcom.com/v2/oauth2/token?"+client1;
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
ResponseEntity<String> response1
= ss.getForEntity(data23 , String.class);
ObjectMapper mapper3 = new ObjectMapper();
JsonNode root = mapper3.readTree(response1.getBody());
System.out.println(root);
// Manually converting the response body InputStream to APOD using Jackson
ObjectMapper mapper = new ObjectMapper();
// Finally we have the response
//System.out.println(apod.title);
RequestBody body = RequestBody.create(mediaType,client1 );
Request request = new Request.Builder()
.url("https://api.dexcom.com/v2/oauth2/token")
.post(body)
.addHeader("content-type:", "application/x-www-form-urlencoded")
.addHeader("cache-control", "no-cache")
.build();
ObjectMapper mapper1 = new ObjectMapper();
Response response = client.newCall(request).execute();
Map<String, Object> studentMap1 = mapper.convertValue(response, Map.class);
System.out.println(studentMap1);
return response;
}
@GetMapping("/")
public String wow() {
return "nice";
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(
"/index.html","/error").permitAll().anyRequest().authenticated();
}
}
通过重定向 uri 是 /login
我的依赖
<?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 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>googleauth</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dexcomapi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars/webjars-locator -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.40</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我的application.yml
security:
oauth2:
client:
clientId: Ncv8kRTLDnWM1oVeAuQRFFQugcBwIME2
clientSecret: 2sI8N7eY3dW50GK
accessTokenUri: https://api.dexcom.com/v2/oauth2/token
userAuthorizationUri: https://api.dexcom.com/v2/oauth2/login
tokenName: oauth_token
authenticationScheme: header
clientAuthenticationScheme: header
scope: offline_access
resource:
userInfoUri: https://api.dexcom.com/v2/users/self/dataRange
我的前端代码与 angular js
<body ng-app="app" ng-controller="home as home">
<h1>Login</h1>
<div class="container" ng-show="!home.authenticated">
With Fitbit: <a href="/login">click here</a>
</div>
<div class="container" ng-show="home.authenticated">
Logged in as: <span ng-bind="home.user"></span><br />
Lifetime Steps: <span ng-bind="home.lifetimeSteps"></span><br />
Lifetime Distance: <span ng-bind="home.lifetimeDistance"></span><br />
Lifetime Floors: <span ng-bind="home.lifetimeFloors"></span><br />
</div>
<script type="text/javascript" src="/webjars/angularjs/angular.min.js"></script>
<script type="text/javascript">
angular.module("app", []).controller("home", function($http) {
var self = this;
$http.get("/login").success(function(data) {
self.user = data.userAuthentication.details.user.fullName;
self.authenticated = true;
}).error(function() {
self.user = "N/A";
self.authenticated = false;
});
$http.get("/loginDexcom").success(function(data) {
self.lifetimeSteps = data.steps.toLocaleString();
self.lifetimeFloors = data.floors.toLocaleString();
self.lifetimeDistance = data.distance.toLocaleString();
}).error(function() {
self.lifetimeSteps = "N/A";
});
});
</script>
</body>
谢谢
通过将重定向 URI 显式设置为 http://localhost:8080/login
,您可以覆盖默认的重定向 URI,即 /login/oauth2/callback/{registrationId}
。
这个 URI 很特殊,因为它提示 OAuth2LoginAuthenticationFilter
处理请求,尝试对用户进行身份验证并创建 OAuth2AuthenticationToken
。
当您将重定向 URI 设置为 /login
时,不会调用 OAuth2LoginAuthenticationFilter
并且应用程序不知道用户是否已通过身份验证,从而导致 401。
这是我的问题。
我正在尝试使用 springboot 集成 dexcom rest api 来获取用户健康数据。
由 dexcom api 使用 oauth2 流程。
当我点击 link /login 应用程序重定向到 dexcom api 登录页面并询问用户 用户名和密码如果身份验证成功,dexcom 登录页面将重定向到我的 应用程序通过使用此授权发送授权代码重定向 uri 我需要从 dexcom 获取访问令牌,后来我使用 dexcom 获取数据 api.This 是我的项目
我的问题是,在 dexcom 登录页面成功输入用户名和密码后,通过提供授权码验证并重定向到我的应用程序,
http://localhost:8080/login?code=c956626ef691a1abe46bcc827a68ddfb&state=lJCK1p 但在同一页面中,我遇到了以下错误 enter image description here 白标错误页面 此应用程序没有 /error 的显式映射,因此您将其视为后备。
2021 年 6 月 8 日星期二 20:52:24IST 出现意外错误(类型=未授权,状态=401)。
我的代码
package com.example.mystorageapp;
@RestController
@EnableWebSecurity
@EnableOAuth2Sso
public class Dexomapi extends WebSecurityConfigurerAdapter {
//@SuppressWarnings("deprecation")
@GetMapping(value="/login")
public Response get_auth(@RequestParam(value="code",required =false) String code,
@RequestParam(value="state") String state ) throws IOException {
RestTemplate ss=new RestTemplate();
OkHttpClient client = new OkHttpClient();
String client1= (String)"client_secret=t2sI8N7eY3dW50GK&
client_id=XXXXXXXX&code="+code+"&grant_type=
authorization_code&redirect_uri=http://localhost:8080/login";
System.out.println(code);
String data23="https://api.dexcom.com/v2/oauth2/token?"+client1;
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
ResponseEntity<String> response1
= ss.getForEntity(data23 , String.class);
ObjectMapper mapper3 = new ObjectMapper();
JsonNode root = mapper3.readTree(response1.getBody());
System.out.println(root);
// Manually converting the response body InputStream to APOD using Jackson
ObjectMapper mapper = new ObjectMapper();
// Finally we have the response
//System.out.println(apod.title);
RequestBody body = RequestBody.create(mediaType,client1 );
Request request = new Request.Builder()
.url("https://api.dexcom.com/v2/oauth2/token")
.post(body)
.addHeader("content-type:", "application/x-www-form-urlencoded")
.addHeader("cache-control", "no-cache")
.build();
ObjectMapper mapper1 = new ObjectMapper();
Response response = client.newCall(request).execute();
Map<String, Object> studentMap1 = mapper.convertValue(response, Map.class);
System.out.println(studentMap1);
return response;
}
@GetMapping("/")
public String wow() {
return "nice";
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(
"/index.html","/error").permitAll().anyRequest().authenticated();
}
}
通过重定向 uri 是 /login
我的依赖
<?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 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>googleauth</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dexcomapi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars/webjars-locator -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.40</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我的application.yml
security:
oauth2:
client:
clientId: Ncv8kRTLDnWM1oVeAuQRFFQugcBwIME2
clientSecret: 2sI8N7eY3dW50GK
accessTokenUri: https://api.dexcom.com/v2/oauth2/token
userAuthorizationUri: https://api.dexcom.com/v2/oauth2/login
tokenName: oauth_token
authenticationScheme: header
clientAuthenticationScheme: header
scope: offline_access
resource:
userInfoUri: https://api.dexcom.com/v2/users/self/dataRange
我的前端代码与 angular js
<body ng-app="app" ng-controller="home as home">
<h1>Login</h1>
<div class="container" ng-show="!home.authenticated">
With Fitbit: <a href="/login">click here</a>
</div>
<div class="container" ng-show="home.authenticated">
Logged in as: <span ng-bind="home.user"></span><br />
Lifetime Steps: <span ng-bind="home.lifetimeSteps"></span><br />
Lifetime Distance: <span ng-bind="home.lifetimeDistance"></span><br />
Lifetime Floors: <span ng-bind="home.lifetimeFloors"></span><br />
</div>
<script type="text/javascript" src="/webjars/angularjs/angular.min.js"></script>
<script type="text/javascript">
angular.module("app", []).controller("home", function($http) {
var self = this;
$http.get("/login").success(function(data) {
self.user = data.userAuthentication.details.user.fullName;
self.authenticated = true;
}).error(function() {
self.user = "N/A";
self.authenticated = false;
});
$http.get("/loginDexcom").success(function(data) {
self.lifetimeSteps = data.steps.toLocaleString();
self.lifetimeFloors = data.floors.toLocaleString();
self.lifetimeDistance = data.distance.toLocaleString();
}).error(function() {
self.lifetimeSteps = "N/A";
});
});
</script>
</body>
谢谢
通过将重定向 URI 显式设置为 http://localhost:8080/login
,您可以覆盖默认的重定向 URI,即 /login/oauth2/callback/{registrationId}
。
这个 URI 很特殊,因为它提示 OAuth2LoginAuthenticationFilter
处理请求,尝试对用户进行身份验证并创建 OAuth2AuthenticationToken
。
当您将重定向 URI 设置为 /login
时,不会调用 OAuth2LoginAuthenticationFilter
并且应用程序不知道用户是否已通过身份验证,从而导致 401。