首页 > 解决方案 > 指定 EnableResourceServer 时 Spring Boot Security EnableWebSecurity Configure 不起作用

问题描述

我正在尝试在 Spring Boot 应用程序中实现 OAuth2。到目前为止,我能够获得访问令牌并能够访问 url,但我很困惑,当我在我的应用程序中启用资源服务器配置时,具有角色 USER 的用户可以访问 ADMIN 页面,反之亦然。并Authentication设置为true从请求authentication.getName()返回usernameoauth2grant_type=password

框架:

我的代码如下: SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginRepository loginRepository;

    @Autowired
    private TestLoginService testLoginService;

    @Autowired
    private DaoAuthenticationProvider daoAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/register").permitAll()
                .antMatchers("/oauth/token").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }

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

    @Override
    protected UserDetailsService userDetailsService() {
        loginRepository.init(encoder());
        return testLoginService;
    }

    @Bean
    public DaoAuthenticationProvider customAuthenticationProvider() {
        final DaoAuthenticationProvider customAuthenticationProvider = new DaoAuthenticationProvider();
        customAuthenticationProvider.setUserDetailsService(testLoginService);
        customAuthenticationProvider.setPasswordEncoder(encoder());
        return customAuthenticationProvider;
    }

    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
}

OAuth2SecurityConfig.java

@Configuration
@EnableAuthorizationServer
public class OAuth2SecurityConfig extends AuthorizationServerConfigurerAdapter {

    private  static Logger logger = LoggerFactory.getLogger(OAuth2SecurityConfig.class);
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthenticationManager AuthenticationManager;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;


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


    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }


    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        String secret = passwordEncoder.encode("secret");
        logger.info("Secret : " + secret);
        clients
                .inMemory()
                .withClient("client")
                .secret("$2a$10$8ip4rySjPLcCedGRVgvT8OriH7dB2VoWDQfk7V3mvPx/BBV8Yglry")
                .autoApprove(false)
                .authorizedGrantTypes("password", "authorization_code", "implicit", "refresh_token")
                .scopes(Role.ROLE_USER.name(), Role.ROLE_ADMIN.name())
                .redirectUris("http://localhost:8080/code")
                .accessTokenValiditySeconds(3600)
                .refreshTokenValiditySeconds(4800);
    }

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

}

OAuth2ResourceSecurityConfig.java

@Configuration
@EnableResourceServer
public class OAuth2ResourceSecurityConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated();
    }
}

如果我没有配置 OAuth2ResourceSecurityConfig#configure 方法,那么用户或管理员角色用户可以访问任一 url。有人可以向我解释一下配置方法的相关性,OAuth2ResourceSecurityConfig以及SecurityConfig应该使用哪个更清楚。

SecurityController.java

@RequestMapping(value = "/admin", method = RequestMethod.GET)
    public String adminAccess(Authentication authentication) {
        logger.info("Admin access /admin link: " + authentication.getName() + " role: " + authentication.getAuthorities().toString());
        logger.info("Admin User authenticated: " + authentication.isAuthenticated());
        return authentication.getName();
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String userAccess(Authentication authentication) {
        logger.info("User access / : " + authentication.getName() + " role: " + authentication.getAuthorities().toString());
        logger.info("User authenticated: " + authentication.isAuthenticated());
        return authentication.getName();
    }

谢谢你。

标签: spring-bootspring-securityspring-security-oauth2

解决方案


推荐阅读