不知道为什么,授权服务和资源服务分开放两个服务,项目是没问题的,访问资源服务所在项目方法也需要认证授权,但是二者在同一个服务上访问所有方法都不需要认证就可以访问,得不到注入的Authentication authentication
一个服务上(授权和资源服务放在一块)的项目结构分开时项目结构:
这个是资源服务代码@EnableResourceServer//@EnableResourceServer 注解自动增加了一个类型为 OAuth2AuthenticationProcessingFilter 的过滤器链,
@Configuration
@EnableWebSecurity
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();
        
    }
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        super.configure(resources);
        resources.tokenServices(tokenServices());
    }    @Bean
    public JwtTokenStore jwtTokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }    /**
     * resourceServerTokenServices 类的实例,用来实现令牌服务。
     * @return
     */
    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(jwtTokenStore());
        return defaultTokenServices;
    }
}
这个是授权服务代码

@Configuration
@ComponentScan
public class OauthConfiguration implements AuthorizationServerConfigurer  {
    /**
     *无法注入时候在WebSecurityConfigurerAdapter的实现类当中,重写authenticationManagerBean方法:
     */
    @Autowired
    private AuthenticationManager authenticationManager;    @Autowired
    private UserService userService;    /**
     * 用来配置令牌端点(Token Endpoint)的安全约束.
     * @param authorizationServerSecurityConfigurer
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer authorizationServerSecurityConfigurer) throws Exception {
        authorizationServerSecurityConfigurer.allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()")
                .tokenKeyAccess("permitAll()");
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
        clientDetailsServiceConfigurer.inMemory().withClient("itqinbo")
                .secret("123456")//7c42e528-bf84-4563-b5d1-bfcf5ac55559
                .authorizedGrantTypes("password", "refresh_token")
                .refreshTokenValiditySeconds(7 * 24 * 3600 * 1000)
                .accessTokenValiditySeconds(1 * 24 * 3600 * 1000)
                .scopes("read", "write");
    } 
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        endpoints.authenticationManager(authenticationManager());
        endpoints.tokenStore(jwtTokenStore());
        endpoints.accessTokenConverter(accessTokenConverter());
        endpoints.userDetailsService(userService);
        endpoints.pathMapping("/oauth/token","/itqinbo/token");
        ClientDetailsService clientDetails = endpoints.getClientDetailsService();
        AuthorizationServerTokenServices tokenServices = endpoints.getTokenServices();
        AuthorizationCodeServices authorizationCodeServices = endpoints.getAuthorizationCodeServices();
        OAuth2RequestFactory requestFactory = endpoints.getOAuth2RequestFactory();        List<TokenGranter> tokenGranters = new ArrayList<>();
        tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails,
                requestFactory));
        tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
        ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
        tokenGranters.add(implicit);
        tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));        tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager(), tokenServices,
                clientDetails, requestFactory));        endpoints.tokenGranter(new CompositeTokenGranter(tokenGranters));
    }    @Bean
    public JwtTokenStore jwtTokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(jwtTokenStore());
        defaultTokenServices.setSupportRefreshToken(true);        return defaultTokenServices;
    }    public AuthenticationManager authenticationManager() {
        List<AuthenticationProvider> providers = new ArrayList<>();
        providers.add(daoAuthenticationProvider());
        return new ProviderManager(providers, authenticationManager);
    }    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new Md5PasswordEncoder();
    }
}
这个是security配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {    @Autowired
    private UserService userService;  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers( "/login").permitAll();
      
    }    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
     
    }    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }}
自己项目的controller
@RestController
public class TestController {    @RequestMapping(value = "/test",method = RequestMethod.GET)
    public Object test(Authentication authentication){
        String principal = (String) authentication.getPrincipal();
        return new JsonResult(200,"success",principal);
    }}

解决方案 »

  1.   

    两个放在同一个服务上,方法不需要任何认证就可以访问,所以authentication也是null,但是分别放在两个服务上,不加token会提示认证,加token后authentication可以获取到用户信息
    @RestController
    public class TestController {
     
        @RequestMapping(value = "/test",method = RequestMethod.GET)
        public Object test(Authentication authentication){
            String principal = (String) authentication.getPrincipal();
            return new JsonResult(200,"success",principal);
        }
     
    }
      

  2.   

    也碰到这个问题。 原因应该是SecurityConfiguration的配置优先级比ResourceServerConfigurer 优先级高,导致请求首先被SecurityConfiguration拦截了。 解决方案是提高ResourceServerConfigurer的优先级(@order)比 SecurityConfiguration高, 或者让SecurityConfiguration只处理oauth/路径的请求,比如http.csrf().disable()..antMatcher("/oauth/**")..authorizeRequests()...... 
      

  3.   

    我现在有一个困惑, auth2只是做了用户认证, 资源授权判断怎么处理,是交给spring security,做决策吗?如果是这样的 话,springsecurity中的用户认证怎么和auth2对应上
      

  4.   

    球博主的github地址
      

  5.   

    <br />请问解决了吗?我也遇到了这个问题
      

  6.   

    <br />我也遇到了这个问题,请问您解决了吗?