Spring 安全 Java 配置
Posted
技术标签:
【中文标题】Spring 安全 Java 配置【英文标题】:Spring Security Java Config 【发布时间】:2013-12-06 12:33:57 【问题描述】:所以最近我将 Spring 配置从 XML 迁移到 Java 配置。 它是一个 Spring OAuth 2 服务器,一些端点通过客户端身份验证进行保护,一些端点(confirm_access)通过用户身份验证进行保护,用户身份验证通过过滤器(“authenticationFilter”)进行的重定向委托给登录应用程序。 但是我不能对 Spring Security Java 配置做同样的事情:
这是我的工作安全 XML 配置:
<sec:http pattern="/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
entry-point-ref="oauthAuthenticationEntryPoint">
<sec:intercept-url pattern="/token" access="IS_AUTHENTICATED_FULLY" />
<sec:anonymous enabled="false" />
<sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<sec:http pattern="/css/**" security="none" />
<sec:http pattern="/js/**" security="none" />
<sec:http access-denied-page="/errors/access-denied.html" disable-url-rewriting="true" entry-point-ref="authenticationEntryPoint">
<sec:intercept-url pattern="/authorize" access="ROLE_USER" />
<sec:intercept-url pattern="confirm_access" access="ROLE_USER" />
<sec:intercept-url pattern="/device/authorize" access="ROLE_USER" />
<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:custom-filter ref="authenticationFilter" before="ANONYMOUS_FILTER" />
<sec:anonymous />
</sec:http>
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="authenticationProvider" />
</sec:authentication-manager>
<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
这是我的 Java 配置尝试:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@Order(1)
@Import(WebSecurityConfig.TokenEndpointSecurityConfigurationAdapter.class,
WebSecurityConfig.ResourceSecurityConfigurationAdapter.class,
WebSecurityConfig.AnonymousSecurityConfigurationAdapter.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
ClientDetailsUserDetailsService clientDetailsUserService;
@Bean(name = "clientAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(clientDetailsUserService);
@Configuration
@Order(2)
public static class TokenEndpointSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
@Autowired
ClientDetailsUserDetailsService clientDetailsUserService;
@Autowired
OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint;
@Autowired
ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter;
@Autowired
OAuth2AccessDeniedHandler oauthAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception
http
.userDetailsService(clientDetailsUserService)
.anonymous().disable()
.authorizeUrls()
.antMatchers("/token")
.fullyAuthenticated()
.and()
.httpBasic()
.authenticationEntryPoint(oauthAuthenticationEntryPoint)
.and()
.addFilterBefore(clientCredentialsTokenEndpointFilter, BasicAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.stateless)
.and()
.exceptionHandling().accessDeniedHandler(oauthAccessDeniedHandler);
@Configuration
@Order(3)
public static class ResourceSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
@Override
public void configure(WebSecurity web) throws Exception
web
.ignoring()
.antMatchers("/css/**","/js/**");
@Configuration
@Order(4)
public static class AnonymousSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
@Autowired
OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint;
@Autowired
AuthenticationFilter authenticationFilter;
@Autowired
PreAuthenticatedAuthenticationProvider authenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception
http
.authenticationProvider(authenticationProvider)
.addFilterBefore(authenticationFilter, AnonymousAuthenticationFilter.class)
.authorizeUrls().anyRequest().anonymous()
.and()
.authorizeUrls()
.antMatchers("/authorize","confirm_access","/custom/authorize")
.hasRole("USER")
.and()
.exceptionHandling().accessDeniedPage("/errors/access-denied.html");
使用此配置,Spring Security 尝试对所有端点的用户进行身份验证,并显示生成登录表单,因此未添加自定义过滤器。 我的错在哪里?
【问题讨论】:
您需要两个 AuthenticationManager(一个用于 OAuth 客户端,一个用于用户),但我只能在您的基于 java 的配置中看到一个。 你好@Eugen,这是一个很好的例子,对我有帮助。但是我有一些问题,当我在 HttpSecurity 中使用addFilterBefore(clientCredentialsTokenEndpointFilter, BasicAuthenticationFilter.class)
时,我得到以下编译器错误he method addFilterBefore(Filter, Class<? extends Filter>) from the type HttpSecurity refers to the missing type Filter
我如何解决这个问题?
【参考方案1】:
由于您的原始配置仅包含两个 http
元素,因此您的新配置应仅包含两个 WebSecurityConfigurerAdapter
实例。每个WebSecurityConfigurerAdapter
实例都使用http.antMatchers
进行映射。目前WebSecurityConfigurerAdapter
映射到每个 URL。
如何使用多个WebSecurityConfigurerAdapter
实例可以参考an example的参考(相当于)
【讨论】:
以上是关于Spring 安全 Java 配置的主要内容,如果未能解决你的问题,请参考以下文章