You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Spring Bean OAuth集成从XML配置转为Java注解配置

Got it, let's convert your Spring OAuth2 XML configuration to annotation-based code step by step. I'll split this into logical components to match your original setup, so you can map each XML bean directly to the annotated code.

1. Core Web Security Configuration

This class handles the authentication managers and client credentials filter, corresponding to your <sec:authentication-manager> beans and clientCredentialsTokenEndpointFilter:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ClientDetailsService clientDetailsService;

    // Maps to the `clientAuthenticationManager` bean
    @Bean
    public AuthenticationManager clientAuthenticationManager() throws Exception {
        return authenticationManagerBean();
    }

    // Maps to `clientCredentialsTokenEndpointFilter`
    @Bean
    public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() throws Exception {
        ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
        filter.setAuthenticationManager(clientAuthenticationManager());
        return filter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // In-memory user store matching your `<sec:user-service>` setup
        auth.inMemoryAuthentication()
                .withUser("arip")
                .password("{noop}passw0rd") // {noop} tells Spring Security to use plain text (demo only!)
                .authorities("ROLE_USER");

        // Client authentication provider using ClientDetailsUserDetailsService
        auth.authenticationProvider(clientAuthenticationProvider());
    }

    @Bean
    public AuthenticationProvider clientAuthenticationProvider() {
        ClientDetailsUserDetailsService userDetailsService = new ClientDetailsUserDetailsService(clientDetailsService);
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(NoOpPasswordEncoder.getInstance()); // Replace with BCrypt in production
        return provider;
    }
}

2. OAuth2 Helper Beans (Entry Points, Access Denied Handler, Decision Manager)

This class defines the beans for authentication entry points, access denied handling, and the access decision manager:

@Configuration
public class OAuth2ConfigBeans {

    // Maps to `oauthAuthenticationEntryPoint`
    @Bean
    public OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint() {
        OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
        entryPoint.setRealmName("test");
        return entryPoint;
    }

    // Maps to `clientAuthenticationEntryPoint`
    @Bean
    public OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint() {
        OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
        entryPoint.setRealmName("test/client");
        entryPoint.setTypeName("Basic");
        return entryPoint;
    }

    // Maps to `oauthAccessDeniedHandler`
    @Bean
    public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
        return new OAuth2AccessDeniedHandler();
    }

    // Maps to `accessDecisionManager`
    @Bean
    public AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<? extends Object>> voters = new ArrayList<>();
        voters.add(new ScopeVoter());
        voters.add(new RoleVoter());
        voters.add(new AuthenticatedVoter());
        return new UnanimousBased(voters);
    }
}

3. Authorization Server Configuration

This class replaces your /oauth/token HTTP configuration and token-related beans, using @EnableAuthorizationServer:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager clientAuthenticationManager;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint;

    @Autowired
    private OAuth2AccessDeniedHandler oauthAccessDeniedHandler;

    @Autowired
    private ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        // Security rules for the token endpoint
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .authenticationEntryPoint(clientAuthenticationEntryPoint)
                .accessDeniedHandler(oauthAccessDeniedHandler);
        
        // Add client credentials filter after basic auth filter
        security.addTokenEndpointAuthenticationFilter(clientCredentialsTokenEndpointFilter);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // Replace this with your actual client details (database, etc.)
        clients.inMemory()
                .withClient("your-client-id")
                .secret("{noop}your-client-secret") // Use password encoder in production
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .authorities("ROLE_CLIENT");
    }

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

    // Maps to `tokenStore`
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore(); // Replace with JdbcTokenStore or JwtTokenStore in production
    }

    // Maps to `tokenServices`
    @Bean
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(tokenStore());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setAccessTokenValiditySeconds(1000);
        tokenServices.setClientDetailsService(clientDetailsService);
        return tokenServices;
    }

    // Maps to `userApprovalHandler` (completed the partial XML definition)
    @Bean
    public UserApprovalHandler userApprovalHandler() {
        TokenServicesUserApprovalHandler handler = new TokenServicesUserApprovalHandler();
        handler.setTokenServices(tokenServices());
        handler.setClientDetailsService(clientDetailsService);
        return handler;
    }
}

4. Resource Server Configuration

This class secures your /api/** endpoints, using @EnableResourceServer:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint;

    @Autowired
    private OAuth2AccessDeniedHandler oauthAccessDeniedHandler;

    @Autowired
    private AccessDecisionManager accessDecisionManager;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("test")
                .authenticationEntryPoint(oauthAuthenticationEntryPoint)
                .accessDeniedHandler(oauthAccessDeniedHandler)
                .accessDecisionManager(accessDecisionManager);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // Security rules for API endpoints
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
                .and()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers("/api/**").hasRole("USER");
    }
}

Important Notes:

  • Password Encoding: In production, replace NoOpPasswordEncoder with a strong encoder like BCryptPasswordEncoder. The {noop} prefix is only for demo purposes to allow plain-text passwords.
  • Client Details: The in-memory client setup in AuthorizationServerConfig is just an example. You should replace this with a ClientDetailsService that loads clients from a database or other secure store.
  • Token Store: InMemoryTokenStore is fine for testing, but use JdbcTokenStore (database-backed) or JwtTokenStore (stateless JWT tokens) in production.

内容的提问来源于stack exchange,提问作者dnvsp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:19