spring cloud oauth2 token获取后访问资源服务器出现:Full authentication is required to access this resource

伊正 发布于 2018/12/27 12:53
阅读 9K+
收藏 2

spring cloud oauth2 token获取后通过zuul网关访问资源服务器出现:{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
},求大神帮帮忙


项目技术
springboot2.1+spring cloud2.1+oauth2

spring-cloud-demo-eureka:服务注册中心
spring-cloud-demo-auth:授权服务
spring-cloud-demo-provider-auth:普通服务
spring-cloud-demo-zuul:网关

项目截图

 

运行截图

获取token:

调用:

相关代码片段

授权服务代码:

package com.springcloud.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        String finalSecret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");

        // 配置两个客户端,一个用于password认证一个用于client认证
			clients.inMemory()
			.withClient("client_2")
			//.resourceIds(Utils.RESOURCEIDS.ORDER)
			.authorizedGrantTypes("client_credentials","password", "refresh_token")
			.scopes("server")
			//.authorities("oauth2")
			.secret(finalSecret)
			.and()
			.withClient("client_1")
			//.resourceIds(Utils.RESOURCEIDS.ORDER)
			.authorizedGrantTypes("client_credentials", "refresh_token")
			.scopes("select")
			//.authorities("oauth2")
			.secret(finalSecret);
                
               
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    	// 配置授权endpoint
        endpoints.tokenStore(new MyRedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager)
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        // 允许表单认证
        security.allowFormAuthenticationForClients().tokenKeyAccess("permitAll()")//公开/oauth/token的接口
                .checkTokenAccess("isAuthenticated()");
    }
}

 

package com.springcloud.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

        String finalPassword = "{bcrypt}"+bCryptPasswordEncoder.encode("123456");
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user_1").password(finalPassword).authorities("USER").build());
        manager.createUser(User.withUsername("user_2").password(finalPassword).authorities("USER").build());

        return manager;
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/user/**").permitAll();
    }
}

 

配置文件:application.yml

#该文件等同于application.properties
spring:
  application:
    name: auth-demo
#  datasource:
#    url: jdbc:mysql://localhost:3306/zuul-auth?useUnicode=true&characterEncoding=utf-8
#    username: root
#    password: 123456
#    driver-class-name: com.mysql.jdbc.Driver
  redis:
    host: 127.0.0.1
    port: 6379
    #password: 123456
    
server:
  port: 9030
#  servlet:
#    context-path: /uaa
  
eureka: 
  client:
    #此项目不作为客户端注册,若是未禁用eureka服务注册中心的客户端注册行为,需提供service-url注册中心地址:
    register-with-eureka: true    
    #注册中心地址
    service-url:
      #开启权限验证后Eureka地址为 用户名:密码@地址:端口号,如未开启权限验证则直接使用 地址:端口号
      defaultZone:  http://root:root@localhost:8761/eureka
      



 

普通服务:

package com.springcloud.demo.config;

import feign.RequestInterceptor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;


@EnableOAuth2Client
@EnableConfigurationProperties
@Configuration
public class OAuth2ClientConfig {

    @Bean
    @ConfigurationProperties(prefix = "security.oauth2.client")
    public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
        return new ClientCredentialsResourceDetails();
    }

    @Bean
    public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext,
                                                            ClientCredentialsResourceDetails resource) {
        return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource);
    }

    @Bean
    public OAuth2RestTemplate clientCredentialsRestTemplate() {
        return new OAuth2RestTemplate(clientCredentialsResourceDetails());
    }
}

 

package com.springcloud.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)//EnableGlobalMethodSecurity开户方法级别的保护
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
    	http.authorizeRequests()//去掉获取token会被拦截
        .antMatchers("/auth/**").permitAll()//开放的资源不用授权
                .antMatchers("/user/**").authenticated();
    }
}

 配置文件:application.yml

#该文件等同于application.properties
spring:
  application:
    name: provider-demo
  datasource: 
   url: jdbc:mysql://localhost:3306/pub_web?useUnicode=true&characterEncoding=utf-8
   username: root
   password: 123456
   driver-class-name: com.mysql.jdbc.Driver
  jpa: 
   database: MYSQL  
   show-sql: true
server:
  port: 8078

mybatis: 
 mapper-locations : classpath*:/mybatis-mapping/*Mapper.xml
 type-aliases-package : com.springcloud.demo.model

  
eurekaServer: 
 host: localhost
 port: 8761
 user: root
 password: root  
 
eureka: 
  client:
    #此项目不作为客户端注册,若是未禁用eureka服务注册中心的客户端注册行为,需提供service-url注册中心地址:
    register-with-eureka: true    
    #注册中心地址
    service-url:
      #开启权限验证后Eureka地址为 用户名:密码@地址:端口号,如未开启权限验证则直接使用 地址:端口号
      defaultZone:  http://${eurekaServer.user}:${eurekaServer.password}@localhost:8761/eureka,http://${eurekaServer.user}:${eurekaServer.password}@localhost:8762/eureka,http://${eurekaServer.user}:${eurekaServer.password}@localhost:8763/eureka
  
security: 
  oauth2:
    client: 
      clientId: client_2
      id: client_2
      clientSecret: 123456
      userAuthorizationUri: http://localhost:9030/oauth/authorize
      accessTokenUri: http://localhost:9030/oauth/token
      grantType: client_credentials
      scope: server

 

加载中
0
xwtdroid
xwtdroid

你试试access token 前面加个bearer , 有个空格

米饭军
米饭军
回复 @xwtdroid : 就算有,那怎么去解决
伊正
伊正
回复 @xwtdroid : 是指在微服务的项目上增加过滤器吗
xwtdroid
xwtdroid
回复 @伊正 : 8093端口我猜测是网关,可能是网关转发到service的时候请求头没有带上,这个问题我也遇到过。可以在普通项目里面加一个filter,请求到达的时候看看filter里面的request有没有你想要的信息
伊正
伊正
请求的头信息上的参数值是有的
0
返回顶部
顶部