在Spring引导Oauth2中拒绝401 Unauthorized Access

时间:2017-04-05 21:08:12

标签: mysql spring-boot oauth-2.0 access-token spring-security-oauth2

从我的角应用中点击oauth/token API时,我得到 401 Unauthorized Access Denied 错误。我无法弄清楚缺少什么。请帮忙。

以下是我的代码

  

SecurityConfiguration.java

@Order(2)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService customUserDetailsService;



    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    private static String REALM = "MY_TEST_REALM";

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        .addFilterBefore(new WebSecurityConfig(), ChannelProcessingFilter.class)
        .exceptionHandling()
        .and()
        .logout()
        .logoutUrl("/oauth/logout")
        .logoutSuccessHandler(customLogoutSuccessHandler)
        .and()
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers("/uaa/**, /uaa/oauth/token, /uaa/oauth/authorize").hasRole("ADMIN").anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}
  

OAuthConfiguration.java

@Configuration
@EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {

private final transient Logger logger = LoggerFactory.getLogger(OAuthConfiguration.class);

@Autowired
private DataSource dataSource;

@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

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

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

@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
    return new JdbcAuthorizationCodeServices(dataSource);
}

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Autowired
UserDetailsService customUserDetailsService;

@Bean
@Primary
public DefaultTokenServices tokenServices() {
    final DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(tokenStore());
    return tokenServices;
}

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

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
    .authenticationEntryPoint(customAuthenticationEntryPoint);
    oauthServer.addTokenEndpointAuthenticationFilter(
            new BasicAuthenticationFilter(authenticationManager, customAuthenticationEntryPoint));

}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients
    .jdbc(dataSource).passwordEncoder(passwordEncoder())
    .withClient("clientId")
            .authorizedGrantTypes("password", "refresh_token", "authorization_code", "client_credentials",
                    "implicit")
            .authorities("ROLE_ADMIN").scopes("read", "write", "trust").secret("123456")
            .accessTokenValiditySeconds(1800).refreshTokenValiditySeconds(3000);
}
}
  

WebSecurityConfig.java

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebSecurityConfig implements Filter{

     @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Origin, Accept, x-auth-token");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
          response.setStatus(HttpServletResponse.SC_OK);
        } else {
          chain.doFilter(req, res);
        }
      }

      @Override
      public void init(FilterConfig filterConfig) {
      }

      @Override
      public void destroy() {
      }
}
  

ResourceServerConfig.java

@Configuration
@EnableResourceServer

public class ResourceServerConfig extends GlobalMethodSecurityConfiguration {

    @Override
       protected MethodSecurityExpressionHandler createExpressionHandler() {
           return new OAuth2MethodSecurityExpressionHandler();
       }
}
  

application.properties

security.oauth2.client.clientId: clientId
security.oauth2.client.clientSecret: 123456
security.oauth2.client.authorized-grant-types: password,refresh_token,authorization_code,client_credentials
security.oauth2.client.scope: read,write,trust
security.oauth2.client.accessTokenUri=http://localhost:8080/uaa/oauth/token
security.oauth2.client.userAuthorizationUri=http://localhost:8080/uaa/oauth/authorize
security.oauth2.client.authenticationScheme=query
security.oauth2.client.clientAuthenticationScheme=form
security.oauth2.resource.filter-order = 3
spring.oauth2.resource.userInfoUri: http://localhost:8080/uaa/user

1 个答案:

答案 0 :(得分:0)

如果有人遇到类似的问题。以下是解决方案:

JDBCTokenStore中存在问题。我必须创建一个受保护的内部类,它扩展了JdbcTokenStore并定义了我自己的readAccessToken()方法。 这解决了这个问题。