1. ホーム
  2. spring-boot

[解決済み] このリソースにアクセスするには、生成されたアクセストークンを使用して完全な認証を行う必要があります。

2022-02-12 04:19:15

質問事項

私は基本的な認証サーバーを実装しようとしているので、ここで私は同じアプリケーションプロジェクトの下で認証サーバーとリソースサーバーの両方を構成しています。

Authサーバの設定

@Configuration
@EnableAuthorizationServer
@EnableResourceServer
@ComponentScan("comm.sun.auth")
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private static String REALM="APP_REALM";
    private static final int ONE_DAY = 60 * 60 * 24;
    private static final int THIRTY_DAYS = 60 * 60 * 24 * 30;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("Client")
                .secret("Client_Secret")
                .authorizedGrantTypes("password", "refresh_token")
                .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                .scopes("read", "write", "trust")
                //.accessTokenValiditySeconds(ONE_DAY)
                .accessTokenValiditySeconds(3000)
                .refreshTokenValiditySeconds(THIRTY_DAYS);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.realm(REALM)
                .checkTokenAccess("isAuthenticated()");
    }

}

リソースサーバーの設定

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //-- define URL patterns to enable OAuth2 security
        http.
                anonymous().disable()
                .requestMatchers().antMatchers("/api/**")
                .and().authorizeRequests()
                .antMatchers("/api/**")
                .access("hasRole('ADMIN') or hasRole('USER')")
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new OAuth2AccessDeniedHandler());
    }
}

WebSecurityの設定: /oauth/token エンポイントはすべて許可されました。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("pass")
                .roles("ADMIN", "USER").and()
                .withUser("appuser")
                .password("pass123").roles("USER");
    }


    @Override
    @Order(Ordered.HIGHEST_PRECEDENCE)
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/about").permitAll()
                .antMatchers("/app/**").permitAll()
                .antMatchers("/oauth/token").permitAll()
//                .antMatchers("/api/**").permitAll()
                //.antMatchers("/api/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .httpBasic()
                .realmName("APP_REALM");
    }


    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
        TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
        handler.setClientDetailsService(clientDetailsService);
        return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);
        return store;
    }


}

レストコントローラー

@RestController
public class apiControllers {

    @GetMapping( value = "/app/getclients")
    public ResponseEntity getAllClients(){
        return new ResponseEntity("All Clients", HttpStatus.OK);
    }

    @GetMapping( value = "/api/getusers")
    public ResponseEntity getAllUsers(){
        return new ResponseEntity("All Users", HttpStatus.OK);
    }


}

私の問題点 : /oauth/token はアクセストークンを生成しますが、生成されたアクセストークンを使って保護されたリソースにアクセスしようとすると Authorization : Bearer accesstoken と表示されます。

<ブロッククオート
"error": "Unauthorized",
"message": "Full authentication is required to access this resource"

シミラークエスチョンがたくさんありますが、そのほとんどは、次のことに関連しています。 /oauth/token しかし、私のシナリオでは /oauth/token enpointは正常に動作しますが、アクセストークンを使用すると、セキュリティで保護されたソースにアクセスできません。コードに問題があるとは思えないのですが、どなたか解決策をお教えください。私はPOSTMANを使用してエンドポイントをテストし、トークンを生成しています。

アップデイト

build.gradle

version '1.0'

buildscript{
    ext{
        spring_boot_version = '1.5.2.RELEASE'
    }
    repositories{
        mavenCentral()
    }
    dependencies{
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version")
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.3'
    distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}

apply plugin: 'java'
//apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-rest', version: '1.5.4.RELEASE'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.6.RELEASE'
// https://mvnrepository.com/artifact/com.h2database/h2
    compile group: 'com.h2database', name: 'h2', version: '1.4.187'
    // https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-oauth2', version: '1.2.1.RELEASE'

}

解決方法は?

ここで、2つの問題があると思います。

  1. タイプミスがある @GetMapping( value = "/app/getclients") apiではなくappです。
  2. Authorizationヘッダーのフォーマットが間違っているのかもしれません。

ご質問の件、テストプロジェクトを作成しましたが、すべてうまくいっています。ここでそれを確認してください https://github.com/alex-petrov81/stackoverflow-answers/tree/master/full-authentication-is-required-to-access-this-resource