gpt4 book ai didi

java - 如何使用java配置在spring中配置waffle

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:44:41 26 4
gpt4 key购买 nike

我一直在努力使用 spring java 配置让 waffle 与 spring 4.2.5 一起工作。我想我也可以帮助处于相同情况的其他人。

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

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

至少可以说,要在 spring 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 ...

}

安全配置.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();
}
}

为了能够 Autowiring waffle authProvider,我创建了以下包装器类。

WindowsAuthenticationProviderWrapper.java

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

根据要求(由于安全风险,一些代码已被删除)。

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

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));
}
}

编辑

对于那些询问这里的人来说,这是一种实现。 CustomServletRequestWrapper:

class CustomServletRequestWrapper extends HttpServletRequestWrapper {


public CustomServletRequestWrapper(HttpServletRequest request) {
super(request);
}
public String getHeader(String name) {
if(name.equals("Authorization"))
return null;
String header = super.getHeader(name);
return (header != null) ? header : super.getParameter(name); // Note: you can't use getParameterValues() here.
}

public Enumeration getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());

names.addAll(Collections.list(super.getParameterNames()));
names.remove("Authorization");
return Collections.enumeration(names);
}

}

如果您需要更多信息,请毫不犹豫地询问。

关于java - 如何使用java配置在spring中配置waffle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36909226/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com