如何使用Spring的Java Config保护具有多个领域的Web应用程序?

时间:2015-04-09 18:47:09

标签: java spring spring-security spring-java-config

我有一个包含两种资源的Web应用程序。

  • 网页
  • 网络服务

我希望使用一个身份验证提供程序(即CAS)保护网页,使用其他身份验证提供程序(即BASIC身份验证)保护Web服务。

我找到了一个可以工作here的解决方案,但是它使用了XML,如果可能的话我宁愿不使用XML配置。

是否有Java Config解决方案?

2 个答案:

答案 0 :(得分:1)

嗯,花了一段时间才弄清楚如何做到这一点......

基本上我将原来的安全配置类拆分为3个独立的配置类。

这基本上就是我做的...

主要安全配置......

@Configuration
@Import({WebPageSecurityConfig.class, WebServiceSecurityConfig.class})
public class SecurityConfig {
}

网页的安全配置...(网址不以/ service / **开头)

@Configuration
@Order(200)
@EnableWebMvcSecurity
public class WebPageSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(casAuthenticationProvider());
    }

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable();

        http.requestMatcher(new RequestMatcher() {
            @Override
            public boolean matches(final HttpServletRequest request) {
                final String url = request.getServletPath() + StringUtils.defaultString(request.getPathInfo());
                return !(url.startsWith("/service/"));
            }
 });
        http.addFilter(casAuthenticationFilter()).exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint());
        http.authorizeRequests().
            antMatchers("/securedPage").hasAuthority("ROLE_CAS_USER"). // /securedPage can only be accessed by cas user
            anyRequest().permitAll(); // all other pages are unsecured
    }

    // General Application Security (CAS Authentication)

    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        final CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        return casAuthenticationFilter;
    }

    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        final CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl(env.getRequiredProperty("cas.server.url") + "/login");
        casAuthenticationEntryPoint.setServiceProperties(casServiceProperties());
        return casAuthenticationEntryPoint;
    }

    @Bean
    public ServiceProperties casServiceProperties() {
        final ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(env.getRequiredProperty("cas.service.url") + "/j_spring_cas_security_check");
        serviceProperties.setSendRenew(false);
        return serviceProperties;
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        final CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        casAuthenticationProvider.setAuthenticationUserDetailsService(casAuthenticationUserDetailsService());
        casAuthenticationProvider.setServiceProperties(casServiceProperties());
        casAuthenticationProvider.setTicketValidator(casTicketValidator());
        casAuthenticationProvider.setKey("casAuthenticationProviderKey");
        casAuthenticationProvider.setStatelessTicketCache(casStatelessTicketCache());
        return casAuthenticationProvider;
    }

    @Bean
    public AuthenticationUserDetailsService casAuthenticationUserDetailsService() {
        final AbstractCasAssertionUserDetailsService authenticationUserDetailsService = new AbstractCasAssertionUserDetailsService() {

            @Override
            protected UserDetails loadUserDetails(final Assertion assertion) {
                final String username = assertion.getPrincipal().getName();
                final List<GrantedAuthority> authorities = new ArrayList<>();
                authorities.add(new SimpleGrantedAuthority("ROLE_CAS_USER"));                
                return new User(username, "notused", authorities);
            }
        };

        return authenticationUserDetailsService;
    }

    @Bean
    public TicketValidator casTicketValidator() {
        final Saml11TicketValidator ticketValidator = new Saml11TicketValidator(env.getRequiredProperty("cas.server.url"));
        ticketValidator.setTolerance(env.getRequiredProperty("cas.ticket.tolerance", Long.class));
        return ticketValidator;
    }

    @Bean
    public StatelessTicketCache casStatelessTicketCache() {
        final EhCacheBasedTicketCache ticketCache =  new EhCacheBasedTicketCache();
        ticketCache.setCache(casCache());
        return ticketCache;
    }

    @Bean(initMethod = "initialise", destroyMethod = "dispose")
    public Cache casCache() {
        final Cache cache = new Cache("casTickets", 50, true, false, 3600, 900);
        return cache;
    }       

    @Autowired
    private Environment env;
}

RESTful Web服务的安全配置(URL以/ service / **开头)

@Configuration
@Order(300)
@EnableWebMvcSecurity
public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().
            withUser("admin").password("password").authorities(new SimpleGrantedAuthority("ROLE_WS_USER"));
    }

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable();

        http.
            antMatcher("/service/**"). // only process URLs that begin with /service/
            sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and(). // RESTful web services are stateless
            addFilter(wsAuthenticationFilter()).exceptionHandling().authenticationEntryPoint(wsAuthenticationEntryPoint());

        http.authorizeRequests().anyRequest().hasAuthority("ROLE_WS_USER"); // all requests are secured
    }

    // Web Service Security (BASIC Authentication)

    @Bean
    public BasicAuthenticationFilter wsAuthenticationFilter() throws Exception {
        final BasicAuthenticationFilter wsAuthenticationFilter = new BasicAuthenticationFilter(authenticationManager(), wsAuthenticationEntryPoint());
        return wsAuthenticationFilter;
    }

    @Bean
    public BasicAuthenticationEntryPoint wsAuthenticationEntryPoint() {
        final BasicAuthenticationEntryPoint wsAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
        wsAuthenticationEntryPoint.setRealmName("My Realm");
        return wsAuthenticationEntryPoint;
    }

    @Autowired
    private Environment env;
}

答案 1 :(得分:-1)

它解释了如何在文档中创建多个证券

http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#multiple-httpsecurity

这样的事情应该起作用

@EnableWebSecurity
public class MultiHttpSecurityConfig {

    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Resource private UserDetailsService userBasicAuthService;

        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**")
                .userDetailsService(userBasicAuthService)
                .authorizeRequests()
                .and()
                .httpBasic();
        }
    }

    @Configuration
    public static class PagesWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        @Resource private UserDetailsService userCasService;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/pages/**")
                .userDetailsService(userCasService)
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin();
        }
    }

}