如何使用java配置在spring中配置waffle [英] How to configure waffle in spring using java configuration

查看:1415
本文介绍了如何使用java配置在spring中配置waffle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力得到华夫饼与春天4.2.5使用spring java配置工作。我想我也可以在同样的情况下帮助别人。

I have been struggling to get waffle to work with spring 4.2.5 using spring java configuration. And I thought I might as well help others in the same situation.

我们使用自定义preWaffle和postWaffle过滤器来验证用户在通过waffles NTLM协议验证后存在于我们的数据库中。

We use a custom preWaffle and postWaffle filter to authenticate that the user exists in our database after it has been validated via waffles NTLM protocol.

我们还有使用EnableGlobalMethodSecurity注释来授权用户操作的方法。

We also have methods for authorization of a user actions using the EnableGlobalMethodSecurity annotation.

要使这个工作在spring java配置是麻烦一些至少。你可以在下面的答案中找到我们的解决方案。

To get this working in spring java configuration was trouble some to say the least. You can find our solution in the answer below. I hope it will help.

推荐答案

SpringConfiguration.java

SpringConfiguration.java

// ... imports 
@Configuration
@EnableWebMvc
@EnableScheduling
@PropertySources({
    @PropertySource("classpath:app.properties")
    // ... Properties sources
})
@EnableTransactionManagement
@ComponentScan(basePackages = "com.our.package")
public class SpringConfiguration extends WebMvcConfigurerAdapter {

 // Our Spring configuration ...

}

SecurityConfiguration.java

SecurityConfiguration.java

// ... imports 
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

  // Authentication manager configuration
  @Autowired
  private WindowsAuthenticationProviderWrapper authProvider;

  @Autowired
  private AuthenticationManagerBuilder auth;

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

  @Bean
  public AuthenticationManager authenticationManager() throws Exception {
    return auth.getObject();
  }

  // Waffle configuration
  @Bean
  public Filter customPreAuthSecurityFilter() {
    return new CustomPreAuthSecurityFilter();
  }

  @Bean
  public Filter customNegotiateSecurityFilter() {
    return new CustomNegotiateSecurityFilter();
  }

  @Bean
  public WindowsAuthProviderImpl waffleAuthProvider(){
    return new WindowsAuthProviderImpl();
  }

  @Bean(name="negotiateSecurityFilterProvider")
  @Autowired
  public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(){
    NegotiateSecurityFilterProvider bean = new NegotiateSecurityFilterProvider(waffleAuthProvider());
    List<String> protocols = new ArrayList<>();
    protocols.add("Negotiate");
    bean.setProtocols(protocols);
    return bean;
  }

  @Bean
  public BasicSecurityFilterProvider basicSecurityFilterProvider(){
    return new BasicSecurityFilterProvider(waffleAuthProvider());
  }

  @Bean(name="waffleSecurityFilterProviderCollection")
  @Autowired
  public waffle.servlet.spi.SecurityFilterProviderCollection negotiateSecurityFilterProviderCollection() {
    final List<SecurityFilterProvider> lsp = new ArrayList<>();
    lsp.add(negotiateSecurityFilterProvider());
    lsp.add(basicSecurityFilterProvider());
    return new waffle.servlet.spi.SecurityFilterProviderCollection(lsp.toArray(new SecurityFilterProvider[]{}));
  }

  @Bean(name="negotiateSecurityFilterEntryPoint")
  @Autowired
  public waffle.spring.NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint() {
    final waffle.spring.NegotiateSecurityFilterEntryPoint ep = new waffle.spring.NegotiateSecurityFilterEntryPoint();
    ep.setProvider(negotiateSecurityFilterProviderCollection());
    return ep;
  }

  @Bean(name="negotiateSecurityFilter")
  @Autowired
  public waffle.spring.NegotiateSecurityFilter waffleNegotiateSecurityFilter(){
    waffle.spring.NegotiateSecurityFilter bean = new waffle.spring.NegotiateSecurityFilter();
    bean.setRoleFormat("both");
    bean.setPrincipalFormat("fqn");
    bean.setAllowGuestLogin(false);
    bean.setProvider(negotiateSecurityFilterProviderCollection());
    return bean;
  }

  // Static Mappings
  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/assets/**");
  }

  // Security filter chain
  // The custom filters can be removed if you only use waffle 
  // but this is how we added them
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    // A user needs to have the role user and has to be authenticated
    http.exceptionHandling()
      .authenticationEntryPoint(negotiateSecurityFilterEntryPoint()).and()
      .addFilterBefore(customPreAuthSecurityFilter(), BasicAuthenticationFilter.class)
      .addFilterAfter(waffleNegotiateSecurityFilter(), BasicAuthenticationFilter.class)
      .addFilterAfter(customNegotiateSecurityFilter(), BasicAuthenticationFilter.class)
      .authorizeRequests().anyRequest().fullyAuthenticated();
     }
  }



为了能够自动连接waffle authProvider我创建了以下包装类。

To be able to autowire the waffle authProvider I created the following wrapperclass.

WindowsAuthenticationProviderWrapper.java

WindowsAuthenticationProviderWrapper.java

// ... imports 
// This class purpose is only to make the Windows authentication provider autowireable in spring.
@Component
public class WindowsAuthenticationProviderWrapper extends WindowsAuthenticationProvider{}

由于安全风险,代码已被删除。)

As requested (Some code has been stripped due to security risks).

CustomPreAuthFilter.java

CustomPreAuthFilter.java

import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * This filter removes the excess negoatiate header sent by IE. If the client
 * has already authenticated, strip the Authorization header from the request.
 */
public class CustomPreAuthSecurityFilter extends GenericFilterBean {
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    SecurityContext sec = SecurityContextHolder.getContext();
    HttpServletRequest req = (HttpServletRequest) servletRequest;

    if(sec != null && sec.getAuthentication() != null) {
      req = new CustomServletRequestWrapper(req);
    }

    try {
      filterChain.doFilter(req, servletResponse);
    } catch (RuntimeException e) {
      sendUnauthorized((HttpServletResponse) servletResponse);
    }
  }

  private void sendUnauthorized(HttpServletResponse response) throws IOException {
    logger.warn("error logging in user");
    SecurityContextHolder.clearContext();
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  }
}

CustomNegotiateSecurityFilter.java

CustomNegotiateSecurityFilter.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import waffle.servlet.WindowsPrincipal;
import waffle.spring.WindowsAuthenticationToken;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * Handle post NTLM authentication against system database
 */
public class CustomNegotiateSecurityFilter extends GenericFilterBean {

  @Autowired
  private UserDAO userDAO;

  @Autowired
  Environment env;

  private static final Logger LOGGER = LoggerFactory.getLogger(CustomNegotiateSecurityFilter.class);

  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    final HttpServletRequest request = (HttpServletRequest) req;
    final HttpServletResponse response = (HttpServletResponse) res;
    SecurityContext sec = SecurityContextHolder.getContext();
    Authentication authentication = sec.getAuthentication();

    // Continue filter chain if we are anonymously authenticated or if DB authentication has already happened.
    if (authentication != null && authentication.getClass() == WindowsAuthenticationToken.class) {

      // The user is Authenticated with NTLM but needs to be checked against the DB.
      User user;

      try {
        // fetch user from DB ...
      } catch (Exception e) {
        // The could not be found in the DB.
        sendUnauthorized(response);
        return;
      }

      // The user was found in the DB.
      WindowsPrincipal principal = (WindowsPrincipal)authentication.getPrincipal();
      final CustomAuthenticationToken token = new CustomAuthenticationToken(principal); // This class extends WindowsAuthenticationToken

      // add roles to token ...

      sec.setAuthentication(token);
    }

    chain.doFilter(request, response);
  }

  private void sendUnauthorized(HttpServletResponse response) throws IOException {
    logger.warn("Could not log in user");
    SecurityContextHolder.clearContext();
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  }

  private void addRoleToAuthentication(WindowsAuthenticationToken authentication, String role) {
      for(GrantedAuthority authority : authentication.getAuthorities()) {
        if(authority.getAuthority().equals(role)) {
          return;
        }
      }
      authentication.getAuthorities().add(new SimpleGrantedAuthority(role));
  }
}

如果您需要更多信息, 。

If you need more information don't hessitate to ask.

这篇关于如何使用java配置在spring中配置waffle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆