我正在使用SpringSecurity5.6中内置的实现将SAML集成到Spring应用程序中。许多联机帮助引用了现在不再推荐的外部库实现(https://github.com/spring-projects/spring-security-saml),因此我将遵循以下文档:
https://docs.spring.io/spring-security/reference/servlet/saml2/login/index.html
我有这个交互工作,我现在从SAML认证。以下是配置:
spring:
security:
saml2:
relyingparty:
registration:
adfs:
signing:
credentials:
- private-key-location: "file:///C:/tmp/keys/private.key"
certificate-location: "file:///C:/tmp/keys/public.crt"
identityprovider:
entity-id: << SNIPPED >>
verification.credentials:
- certificate-location: "classpath:saml-certificate/adfs.crt"
singlesignon:
url: << SNIPPED >>
sign-request: true代码现在如下所示:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final RelyingPartyRegistrationRepository _relyingPartyRegistrationRepository;
@Autowired
public WebSecurityConfig(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository {
_relyingPartyRegistrationRepository = relyingPartyRegistrationRepository;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// add auto-generation of ServiceProvider Metadata at {baseUrl}/saml2/service-provider-metadata/ims-adfs
RelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(_relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http
.authorizeRequests()
.antMatchers("/seer.ico", "/monitor", "/**/check").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.and().csrf().ignoringAntMatchers("/servers/**/searches")
.and()
.saml2Login(withDefaults())
.saml2Logout(withDefaults())
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);
}
}问题是,我需要重新映射用户详细信息,以设置正确的角色,并将登录限制在拥有正确Linux权限的用户。权限正在纠正断言中返回的权限;我只需要验证它们是否正确或登录失败。
Security文档中有一节介绍了如何与UserDetailsService进行协调,这似乎正是我所需要的。
但是,当我像实现示例一样实现它时,我现在从Spring中得到以下错误:
没有在回应中找到断言。
以下是更新的代码:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final RelyingPartyRegistrationRepository _relyingPartyRegistrationRepository;
private final AuthenticationService _userDetailsService;
@Autowired
public WebSecurityConfig(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository, AuthenticationService userDetailsService) {
_relyingPartyRegistrationRepository = relyingPartyRegistrationRepository;
_userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
authenticationProvider.setResponseAuthenticationConverter(responseToken -> {
Saml2Authentication authentication = OpenSaml4AuthenticationProvider.createDefaultResponseAuthenticationConverter().convert(responseToken);
Assertion assertion = responseToken.getResponse().getAssertions().get(0);
String username = assertion.getSubject().getNameID().getValue();
UserDetails userDetails = _userDetailsService.loadUserByUsername(username);
authentication.setDetails(userDetails);
return authentication;
});
// add auto-generation of ServiceProvider Metadata at {baseUrl}/saml2/service-provider-metadata/ims-adfs
RelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(_relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http
.authorizeRequests()
.antMatchers("/seer.ico", "/monitor", "/**/check").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.and().csrf().ignoringAntMatchers("/servers/**/searches")
.and()
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)))
.saml2Logout(withDefaults())
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);
}
}因此,这基本上从SAML获得了正确的响应:
.saml2Login(withDefaults())当我切换到它时,SAML响应将丢失断言:
.saml2Login(saml2 -> saml2.authenticationManager(new ProviderManager(authenticationProvider)))我一直在寻找其他解决方案,但就像我说过的,很少有例子不使用过时的Spring SAML库。
有什么想法吗?
发布于 2022-04-01 10:02:15
检查Spring是否正在导入Open的版本3和版本4。如果只使用4版本。
Security示例为SAML2提供了一个示例。项目中的build.gradle包含以下内容:
repositories {
mavenCentral()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
constraints {
implementation "org.opensaml:opensaml-core:4.1.1"
implementation "org.opensaml:opensaml-saml-api:4.1.1"
implementation "org.opensaml:opensaml-saml-impl:4.1.1"
}
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.security:spring-security-saml2-service-provider'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
testImplementation 'net.sourceforge.htmlunit:htmlunit:2.44.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.awaitility:awaitility:4.2.0'
}参考文献:
https://stackoverflow.com/questions/71622213
复制相似问题