要使用生成的访问令牌访问此资源,必须进行完全身份验证

时间:2018-08-27 20:25:14

标签: spring-boot authentication oauth-2.0 authorization spring-security-oauth2

我正在尝试实现基本的授权服务器,因此在这里,我已经在同一Application项目下配置了Auth Server和资源服务器。

身份验证服务器配置

@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进行注册

@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会产生访问令牌,但是当我尝试使用通用访问密钥Authorization : Bearer accesstoken访问受保护的资源时,它会给出

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

可能有很多模拟问题,但大多数与/oauth/token命题有关。但是在我的senario /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 个答案:

答案 0 :(得分:0)

我认为您在这里遇到了两个麻烦

  1. 有一个错字@GetMapping( value = "/app/getclients")应用而不是api。
  2. 也许您使用了错误的Authorization标头格式。

我已经为您的问题创建了测试项目,一切都很好。请在此处https://github.com/alex-petrov81/stackoverflow-answers/tree/master/full-authentication-is-required-to-access-this-resource

进行检查

答案 1 :(得分:0)

我也遇到了这个错误。我通过在 application.properties 中编写以下内容来解决此问题

security.oauth2.resource.filter-order=3