gpt4 book ai didi

spring - Java - Spring security、Shibboleth (apache) 和 onelogin

转载 作者:行者123 更新时间:2023-12-02 02:47:21 25 4
gpt4 key购买 nike

实际的Spring Security配置是这样的:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/uri1/**").hasAuthority(Permission.AUTHORITY1.toString())
.antMatchers("/uri2/**").hasAuthority(Permission.AUTHORITY2.toString())
.anyRequest().hasAuthority(Permission.AUTHORITY3.toString())
.and().httpBasic()
.realmName("App").and().csrf().disable();
http.authorizeRequests();
http.headers().frameOptions().sameOrigin().cacheControl().disable();
}

@Bean
public Filter shallowEtagHeaderFilter() {
return new ShallowEtagHeaderFilter();
}
}

Web MVC 配置是这样的:

@Configuration
public class DefaultView extends WebMvcConfigurerAdapter{

@Override
public void addViewControllers( ViewControllerRegistry registry ) {
registry.addViewController( "/" ).setViewName( "forward:myPage.html" );
registry.setOrder( Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers( registry );
}
}

我必须使用 onelogin 进行身份验证来替换 Spring Security 中完成的 httpBasic 身份验证(如果我了解在 Internet 上找到的内容,则使用 SAML)。

通过研究,我发现一种可能是在 Apache 服务器上使用 Shibboleth,另一种是使用 Spring Security 中的插件来管理 SAML。

对于第一个解决方案(shibboleth),目的是直接在 Apache 服务器上管理 onelogin 身份验证(如果未连接,用户将被重定向到 onelogin 身份验证页面,如果连接,则可以访问资源)并返回所需的信息在请求 header 中的 SAML 响应(例如用户名和其他需要的数据)中(以便能够在 Spring 应用程序中使用它们)。

通过这个解决方案,是否可以在 Spring security 中保留 httpBasic 身份验证,并在 Shibboleth 设置的每个请求的 header 中包含“Basic XXXX”?或者,我是否需要从 Spring Security 中删除 httpBasic 身份验证?

对于第二个解决方案(在 Spring Security 中管理 SAML 的插件),它与第一个解决方案的结果相同吗?它必须如何实现?

预先感谢您的回复。

最佳答案

欢迎来到 stackoverflow。

... and to have needed informations returned in SAML response (likeusername and other need data) in the header of the request (to beabble to have them in Spring app)

如果我理解正确的话,你已经在使用 spring security 了。这意味着您的应用程序已经在 Controller /服务层中使用 spring security 填充的上下文进行身份验证和授权。如果您使用上述方法,其中 apache 在 header 中填充验证用户信息,那么这本身不会填充 spring 安全上下文,除非您添加 preAuthFilter在您的链中提取此信息并适本地填充您的 spring 上下文。

With this solution, is it possible to keep httpBasic authentificationin Spring security and to have "Basic XXXX" in the header of eachrequest set by Shibboleth? Or, have I to remove the httpBasicauthentification from Spring Security?

如果你能做到的话,我上面说的就轻松一些了。话虽如此,据我所知,没有任何选项可以使用 shibboleth apache 模块推导出基本身份验证 header 。此外,我还建议谨慎使用这种方法,因为使用这种方法,您仍然需要使用虚拟密码对应用程序中的用户进行身份验证(因为您不会通过 SAML 获取用户的正确密码)此 header ),这会打开您的应用程序的安全漏洞。我强烈建议不要采用这种方法。 Shibboleth 已经有一些 Spoof Checking他们的文档中有介绍。

[编辑]根据附加信息,以下是您可以执行以下操作来实现 apache 的所有处理并仍然有效地使用 spring security

首先提供PreAuthenticatedAuthenticationToken的实现在您的应用程序中,您可以使用 AbstractPreAuthenticatedProcessingFilter以此目的。下面提供了实现的框架,这是我过去的一项工作的摘录,并且非常精简,仅保留与您的场景相关的基本元素。另请仔细查看 AuthenticationManagerAuthentication文档并确保您完全理解要使用什么以及用于什么目的。请仔细阅读所有这 4 个类的 javadoc 以理解契约,否则在 Spring Security 中正确理解它可能会令人困惑。我已经在框架中添加了必要的细节作为 TODO 和注释,您必须在实现中自行填写。

public class ShibbolethAuthFilter extends AbstractPreAuthenticatedProcessingFilter {
private final String containsValidPrincipalHeader = "_valid_shibboleth_header_present";
private final String shibbolethHeader = "_shibboleth_header";
private Logger logger = LoggerFactory.getLogger(getClass());

/**
* This authentication manager's authenticate method MUST return a fully populated
* org.springframework.security.core.Authentication object. You may very well use
* either PreAuthenticatedAuthenticationToken OR UsernamePasswordAuthenticationToken
* with any credentials set, most important is to correctly populate the Authorities
* in the returned object so that hasAuthority checks works as expected.
*
* Another point, you can use authentication.getPrincipal() in the implementation
* of authenticate method to access the same principal object as returned by
* getPreAuthenticatedPrincipal method of this bean. So basically you pass the
* using Principal object from this bean to AuthenticationManager's authenticate
* method which in turn return a fully populated spring's Authentication object
* with fully populated Authorities.
*/
@Autowired
private ShibbolethAuthenticationManager authenticationManager;

@Override
public void afterPropertiesSet() {
setAuthenticationManager(authenticationManager);
super.afterPropertiesSet();
}

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String authHeader = request.getHeader(shibbolethHeader);
if (authHeader == null) {
logger.trace("No {} header found, skipping Shibboleth Authentication", shibbolethHeader);
return null;
}
// TODO - validate if all header and it's contents are what they should be
ShibbolethAuthToken authToken = /* TODO - provide your own impl to supply java.security.Principal object here */;
request.setAttribute(containsValidPrincipalHeader, Boolean.TRUE);
return authToken;
}

/**
* No password required thus Credentials will return null
*/
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
if (Boolean.TRUE.equals(request.getAttribute(containsValidPrincipalHeader)))
return System.currentTimeMillis(); // just returning non null value to satisfy spring security contract
logger.trace("Returning null Credentials for non authenticated request");
return null;
}
}

使用以下注册器在您的应用程序中将其注册为 servlet 过滤器

@Configuration
public class ShibbolethFilterRegistrar {

/*
* We don't want to register Shibboleth Filter in spring global chain thus
* added this explicit registration bean to disable just that.
*/
@Bean
public FilterRegistrationBean shibbolethFilterRegistrar(Shibboleth shibbolethAuthFilter) {
FilterRegistrationBean registration = new FilterRegistrationBean(shibbolethAuthFilter);
registration.setEnabled(false);
return registration;
}

@Bean
public ShibbolethAuthFilter shibbolethAuthFilter() {
return new ShibbolethAuthFilter();
}
}

接下来,将您的 WebSecurityConfig 更改为以下内容

@Override
protected void configure(HttpSecurity http) throws Exception {
/* autowire shibbolethAuthFilter bean as well */
http
.addFilterBefore(shibbolethAuthFilter, AbstractPreAuthenticatedProcessingFilter.class);
.authorizeRequests()
.antMatchers("/uri1/**").hasAuthority(Permission.AUTHORITY1.toString())
.antMatchers("/uri2/**").hasAuthority(Permission.AUTHORITY2.toString())
.anyRequest().hasAuthority(Permission.AUTHORITY3.toString())
.and()
.realmName("App").and().csrf().disable();
http.authorizeRequests();
http.headers().frameOptions().sameOrigin().cacheControl().disable();
}

希望这些提示可以帮助您成功集成外部身份验证。

恕我直言,以下内容仍然有效 - 据我了解您的场景,如果我必须这样做,我个人更喜欢使用 spring security 内置的 SAML 身份验证来实现此目的,因为这提供了与 spring security 的非常平滑的集成在框架内的每一个可能的背景下。此外,它还简化了我的部署场景,在该场景中我还必须负责配置 apache,这通常会给 DevOps 团队带来额外的工作量。为了简单性和可扩展性,Spring Security 内置的 SAML SSO 支持将是我的第一选择,除非存在迫使我这样做的约束(根据所提供的解释,我在当前的讨论上下文中无法看到这一点)。网上有足够的教程和示例来完成它。我知道这不是您所要求的,但我想与您分享我自己过去在 Spring 分布式应用程序中为类似的 SSO 解决方案所做的工作以及我所学到的知识。希望它有帮助!!

关于spring - Java - Spring security、Shibboleth (apache) 和 onelogin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62591369/

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