【问题标题】:Authentication is not working in spring boot 1.5.2 and Oauth2身份验证在 spring boot 1.5.2 和 Oauth2 中不起作用
【发布时间】:2017-07-28 14:12:45
【问题描述】:

我正在使用带有 Spring Boot 1.5.2.RELEASE 的 Oauth2。当我试图覆盖 ResourceServerConfigurerAdapter 类的配置方法时,它给了我一个编译错误。但这适用于 Spring boot 1.2.6.RELEASE。

下面是我的代码,

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .exceptionHandling()
        .authenticationEntryPoint(customAuthenticationEntryPoint)
        .and()
        .logout()
        .logoutUrl("/oauth/logout")
        .logoutSuccessHandler(customLogoutSuccessHandler)
        .and()
        .csrf()
        .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
        .disable()
        .headers()
        .frameOptions().disable()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/hello/").permitAll()
        .antMatchers("/secure/**").authenticated();
}

以上代码在 Spring Boot 1.2.6 中运行良好,但在 1.5.2 版本中尝试调用 sessionManagement() 方法时出现编译错误。我猜该方法已在新版本中删除。

但是当我尝试使用 disable().and().sessionManagement() 时,编译错误会消失,但身份验证没有按预期工作。谁能帮我解决这个问题。

下面是我的完整代码

@Configuration
public class OAuth2Configuration {

    @Configuration
    @EnableResourceServer
    @ComponentScan(basePackages = "security")
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Autowired
        private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

        @Autowired
        private CustomLogoutSuccessHandler customLogoutSuccessHandler;

        @Override
        public void configure(HttpSecurity http) throws Exception {

            http
                .exceptionHandling()
                .authenticationEntryPoint(customAuthenticationEntryPoint)
                .and()
                .logout()
                .logoutUrl("/oauth/logout")
                .logoutSuccessHandler(customLogoutSuccessHandler)
                .and()
                .csrf()
                .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
                .disable()
                .headers()
                .frameOptions().disable().and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/hello/").permitAll()
                .antMatchers("/secure/**").authenticated();

        }

    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {

        private static final String ENV_OAUTH = "authentication.oauth.";
        private static final String PROP_CLIENTID = "clientid";
        private static final String PROP_SECRET = "secret";
        private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";

        private RelaxedPropertyResolver propertyResolver;

        @Autowired
        private DataSource dataSource;

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

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

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

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients
                .inMemory()
                .withClient(propertyResolver.getProperty(PROP_CLIENTID))
                .scopes("read", "write")
                .authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_USER.name())
                .authorizedGrantTypes("password", "refresh_token")
                .secret(propertyResolver.getProperty(PROP_SECRET))
                .accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
        }


        public void setEnvironment(Environment environment) {
            this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
        }

    }

}

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new StandardPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());

    }

    @Override
    public void configure(WebSecurity web) throws Exception {

        web
            .ignoring()
            .antMatchers("/h2console/**")
            .antMatchers("/api/register")
            .antMatchers("/api/activate")
            .antMatchers("/api/lostpassword")
            .antMatchers("/api/resetpassword")
            .antMatchers("/api/hello");

    }

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

    @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
    private static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
        @Override
        protected MethodSecurityExpressionHandler createExpressionHandler() {
            return new OAuth2MethodSecurityExpressionHandler();
        }

    }

}

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private final Logger log = LoggerFactory.getLogger(CustomAuthenticationEntryPoint.class);

    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException ae) throws IOException, ServletException {

        log.info("Pre-authenticated entry point called. Rejecting access");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");

    }
}

【问题讨论】:

  • @Tom 不。这不是那个问题的重复。请仔细看看。这是完全不同的。
  • 过滤顺序不是这里的问题。问题是他们改变了 WebSecurityConfigurerAdapter 的 api。我的问题是关于更改与 api 更改相关的配置方法实现?请不要仅仅看问题的表面就试图制造无用的cmets。在做出判断之前,请仔细查看问题。
  • 遇到了同样的问题,我的代码在 1.4.2 上运行良好,但在 1.5.2 下无法正常运行。你找到解决办法了吗?

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


【解决方案1】:

是的。 API有点改变。 sessionManagement 方法可以通过 HttpSecurity 的引用来调用。

http
    .exceptionHandling()
    .authenticationEntryPoint(customAuthenticationEntryPoint)
    .and()
    .logout()
    .logoutUrl("/oauth/logout")
    .logoutSuccessHandler(customLogoutSuccessHandler)
    .and()
    .csrf()
    .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
    .disable()
    .headers()
    .frameOptions().disable();

http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and()
    .authorizeRequests()
    .antMatchers("/hello/").permitAll()
    .antMatchers("/secure/**").authenticated();

但是,您没有提供足够的信息来解决您的身份验证问题。对以下问题的回答可以解决您的问题。

Spring boot Oauth 2 configuration cause to 401 even with the permitall antMatchers

【讨论】:

    【解决方案2】:

    根据Spring Boot 1.5 Release Notes

    OAuth 2 资源过滤器

    OAuth2 资源过滤器的默认顺序已从 3 更改为 SecurityProperties.ACCESS_OVERRIDE_ORDER - 1。这将其放置在执行器端点之后,但在基本身份验证过滤器链之前。可以通过设置 security.oauth2.resource.filter-order = 3 恢复默认值

    所以只需将security.oauth2.resource.filter-order = 3 添加到您的application.properties 即可解决此问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 2017-10-01
      • 2017-10-25
      • 2019-03-21
      • 1970-01-01
      相关资源
      最近更新 更多