Spring Boot、Spring Cloud Security、Spring Cloud OAuth2を使用して認証サーバーを実装しようとしています。
http:// localhost:8080/auth/oauth/token 郵便配達人からヒットしようとすると、以下のエラーになります
{「エラー」:「無許可」、「error_description」:「このリソースにアクセスするには完全な認証が必要です」}
以下は私の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.teckink.tp</groupId>
<artifactId>tp-auth-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>tp-auth-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.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>
<spring-cloud.version>Finchley.M9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
Starter(Main)クラス:
package com.teckink.tp.authserver;
import Java.util.HashMap;
import Java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@EnableResourceServer
@EnableAuthorizationServer
public class App {
@RequestMapping(value = { "/user" }, produces = "application/json")
public Map<String, Object> user(OAuth2Authentication user) {
Map<String, Object> userInfo = new HashMap<>();
userInfo.put("user", user.getUserAuthentication().getPrincipal());
userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));
return userInfo;
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
クライアントとそのシークレットを定義するOAuth2Configクラス:
package com.teckink.tp.authserver.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("eagleeye")
.secret("thisissecret")
.authorizedGrantTypes("refresh_token", "password", "client_credentials")
.scopes("webclient", "mobileclient");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
メモリ内のユーザー、パスワード、およびロールを定義するWebSecurityConfigurerクラス:
package com.teckink.tp.authserver.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john.carnell").password("password1").roles("USER")
.and()
.withUser("william.woodward").password("password2").roles("USER", "ADMIN");
}
}
実行時のサンプルアプリでは、次の例外が発生します。
Java.lang.IllegalArgumentException:ID「null」にマップされたPasswordEncoderはありません
Spring-security-core:5.0では、デフォルトのPasswordEncoderはDelegatingPasswordEncoderとして構築されています。したがって、ユーザーをメモリに保存するときは、パスワードをプレーンテキストで提供し、DelegatingPasswordEncoderからエンコーダを取得してパスワードを検証しようとすると、パスワードが見つかりません。
このリンクの詳細 パスワードエンコーディング
これに対処するには、実稼働実装では、BCryptPasswordEncoder
のインスタンスをアクティブ化する必要があります
開発のために、次の変更を試して、{noop}
をパスワード値に。これは、デフォルトのNoOpPasswordEncoder
の代わりにDelegatingPasswordEncoder
をアクティブにすることでパスワードを扱い、パスワードをプレーンテキストとして扱います。
OAuth2Configクラス
clients.inMemory()
.withClient("eagleeye")
.secret("{noop}thisissecret")
.authorizedGrantTypes("refresh_token", "password", "client_credentials")
.scopes("webclient", "mobileclient");
WebSecurityConfigurerクラス
auth
.inMemoryAuthentication()
.withUser("john.carnell"). password("{noop}password1").roles("USER")
.and()
.withUser("william.woodward").password("{noop}password2").roles("USER", "ADMIN");
これで、Postmanから試行すると、トークンを生成できるようになります
[〜#〜] edit [〜#〜]
動作するデモを使用したGithubプロジェクト こちら
投稿で許可タイプが「パスワード」ではなく「パスワード」としてリストされていることに気付きました。それを修正してもう一度試してください。
同じ問題があります。 URLが間違っている場合は、 http:// localhost:8080/oauth/token に変更してかまいません。間違ったURLを提供している本からこのサンプルを入手しました。 「/ auth」を削除するだけです
ここで奇妙な同じことが起こりました。 curlコマンドを使用して解決しました。
curl -v -X POST http://url:8080/api/oauth/token -u "yourclientid:yourclient_secret" -d "grant_type=password" -d "username=yourusername" -d "password=yourpassword"
または、郵便配達員で必要な場合は、承認に移動します->タイプOAUTH2を選択します->アクセストークンを取得します ここに画像の説明を入力します