Для доступа к этому ресурсу с помощью сгенерированного токена доступа требуется полная аутентификация - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь реализовать базовый сервер авторизации, поэтому здесь я настроил и сервер аутентификации, и сервер ресурсов в одном проекте приложения.

Настройка сервера аутентификации

@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 Config: /oauth/token enpoint был разрешен для каждого

@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;
    }


}

RestControllers

@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 генерирует токен доступа, но когда я пытаюсь получить доступ к защищенным ресурсам с помощью ключа доступа genarated Authorization : Bearer accesstoken, он дает

"error": "Unauthorized",
"message": "Full authentication is required to access this resource"

Может быть много похожих вопросов, но большинство из них связаны с /oauth/token enpoint. но в моем senario /oauth/token enpoint работает нормально, но с токеном доступа я не могу получить доступ к защищенным источникам. Я не вижу проблем с кодом, который кто-либо может направить мне к решению. Я использую POSTMAN для проверки конечных точек и генерации токенов

UPDATE

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'

}

1 Ответ

0 голосов
/ 28 августа 2018

Я думаю, у вас есть две проблемы здесь

  1. Вместо API есть приложение @GetMapping( value = "/app/getclients") с опечаткой.
  2. Возможно, вы используете неправильный формат заголовка авторизации.

Я создал тестовый проект для вашего вопроса, и там все в порядке. Пожалуйста, проверьте это здесь https://github.com/alex-petrov81/stackoverflow-answers/tree/master/full-authentication-is-required-to-access-this-resource

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...